JUC练习17——锁
一,公平锁和非公平锁
公平锁:先来先执行,不能插队
非公平锁:可以插队,默认是非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
二,可重入锁(递归锁)
拿到外层的锁就会自动获取里面的锁

代码示例:
/**
* 由于synchronized 是可重入锁,所以call的锁和sms的锁是同时拿到的
* 因此在A线程执行完sms方法时,B线程是无法执行sms方法的,需要等到A线程一起释放锁
*/
public static void main(String[] args) {
Phones phone = new Phones();
new Thread(()->
{
phone.call();
},"A").start();
new Thread(()->
{
phone.sms();
},"B").start();
}
class Phones
{
public synchronized void call()
{
sms();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": call");
}
public synchronized void sms()
{
System.out.println(Thread.currentThread().getName()+":sms");
}
}
执行结果
A:sms
A: call
B:sms
三,自旋转锁
会不断的去尝试,直到成功为止,会使用到while循环
@HotSpotIntrinsicCandidate
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
return v;
}
自定义自旋锁
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
public class MyLock {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void lock()
{
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"尝试获取锁");
//将当前的线程和null进行比较,不满足则一直循环等待
while (!atomicReference.compareAndSet(null,thread))
{
}
System.out.println(thread.getName()+"成功获取锁");
}
public void unlock()
{
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"解锁");
//将当前的线程和null进行比较,不满足则一直循环等待
atomicReference.compareAndSet(thread,null);
}
public static void main(String[] args) {
MyLock myLock = new MyLock();
new Thread(()->
{
try {
myLock.lock();
TimeUnit.SECONDS.sleep(1);
System.out.println("线程A执行操作");
} catch (Exception e) {
e.printStackTrace();
}finally {
myLock.unlock();
}
},"A").start();
new Thread(()->
{
try {
TimeUnit.SECONDS.sleep(2);
myLock.lock();
System.out.println("线程B执行操作");
} catch (Exception e) {
e.printStackTrace();
}finally {
myLock.unlock();
}
},"B").start();
}
}
测试结果:线程A先得到锁,线程B想要执行必须等线程A释放锁才可以执行
A尝试获取锁
A成功获取锁
线程A执行操作
A解锁
B尝试获取锁
B成功获取锁
线程B执行操作
B解锁
四,如何排查死锁
浙公网安备 33010602011771号