公平锁、非公平锁:
/**
* 公平锁、非公平锁
* 公平锁:非常公平,不能够插队,必须先来后到
* 非公平锁:非常不公平,可以插队(默认都是非公平锁)
*/
ReentrantLock类源代码
ReentrantLock() 空参构造器自动创建非公平锁 new NonfairSync()
如果有参数则判断是否创建公平锁 sync = fair ? new FairSync() : new NonfairSync()
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
可重入锁:
/**
* 可重入锁:
* 可重入锁(递归锁)
* 拿到外面的锁之后,就可以拿到里面的锁,自动获得
*/
Phone phone = new Phone();
new Thread(() -> {
phone.sms();
}, "A").start();
new Thread(() -> {
phone.sms();
}, "B").start();
class Phone {
Lock lock = new ReentrantLock();
public void sms() {
lock.lock(); //锁必须配对,否则会死锁;
try {
System.out.println(Thread.currentThread().getName() + "->" + "sms");
call();//这里也有锁
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void call() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "->" + "call");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
自旋锁:
/**
* 自旋锁
* 自定义一个锁测试:
*/
SpinlockDemo lock = new SpinlockDemo();
new Thread(() -> {
lock.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.myUnLock();
}, "T1").start();
new Thread(() -> {
lock.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.myUnLock();
}, "T2").start();
class SpinlockDemo {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
//加锁
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(thread.getName() + "-->" + "myLock");
//自旋锁
while (!(atomicReference.compareAndSet(null, thread))) {
}
}
//解锁
public void myUnLock() {
Thread thread = Thread.currentThread();
System.out.println(thread.getName() + "-->" + "myUnLock");
atomicReference.compareAndSet(thread, null);
}
}
死锁:
/**
* 死锁:
* 两个线程互相握着对方的锁不放手,则会出现死锁;
*
* 死锁解决办法:
* 1、使用 jps -l 定位进程号
* 2、使用 jstack 进程号 找到死锁问题
*
* 工作面试中:排查死锁问题!!!
* 1、查看日志
* 2、查看堆栈
*
* 死锁演示:
*/
String lockA = "锁A";
String lockB = "锁B";
new Thread(new MyThread(lockA, lockB), "T1").start();
new Thread(new MyThread(lockB, lockA), "T2").start();
class MyThread implements Runnable {
private String lockA;
private String lockB;
public MyThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA) {
System.out.println(Thread.currentThread().getName() + "lockA:" + lockA + "-GET-" + lockB);
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB) {
System.out.println(Thread.currentThread().getName() + "lockB:" + lockB + "-GET-" + lockA);
}
}
}
}