1、公平锁、非公平锁
公平锁: 非常公平, 不能够插队,必须先来后到!
非公平锁:非常不公平,可以插队 (默认都是非公平)
1 2 3 4 5 6 7
| public ReentrantLock() { sync = new NonfairSync(); }
public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); }
|
2、可重入锁
可重入锁(递归锁
Synchronized版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Demo01 { public static void main(String[] args) { Phone phone = new Phone();
new Thread(()->{ phone.sms(); },"A").start();
new Thread(()->{ phone.sms(); },"B").start(); } }
class Phone{
public synchronized void sms(){ System.out.println(Thread.currentThread().getName() + "sms"); call(); }
public synchronized void call(){ System.out.println(Thread.currentThread().getName() + "call"); } }
|
Lock 版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class Demo02 { public static void main(String[] args) { Phone2 phone = new Phone2();
new Thread(()->{ phone.sms(); },"A").start();
new Thread(()->{ phone.sms(); },"B").start(); } }
class Phone2{ Lock lock = new ReentrantLock();
public void sms(){ lock.lock(); 则就会死在里面 lock.lock(); try { System.out.println(Thread.currentThread().getName() + "sms"); call(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); lock.unlock(); }
}
public void call(){
lock.lock(); try { System.out.println(Thread.currentThread().getName() + "call"); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
|
3、自旋锁
spinlock
自定义一个锁测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
public class SpinlockDemo {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void myLock(){ Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName() + "==> mylock");
while (!atomicReference.compareAndSet(null,thread)){
} }
public void myUnLock(){ Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName() + "==> myUnlock"); atomicReference.compareAndSet(thread,null); }
}
|
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public class TestSpinLock { public static void main(String[] args) throws InterruptedException {
SpinlockDemo lock = new SpinlockDemo();
new Thread(()-> { lock.myLock();
try { TimeUnit.SECONDS.sleep(5); } catch (Exception e) { e.printStackTrace(); } finally { lock.myUnLock(); }
},"T1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()-> { lock.myLock();
try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); } finally { lock.myUnLock(); }
},"T2").start();
} }
|
4、死锁
死锁测试,怎么排除死锁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public class DeadLockDemo { public static void main(String[] args) {
String lockA = "lockA"; String lockB = "lockB";
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() + "lock:"+lockA+"=>get"+lockB);
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
synchronized (lockB){ System.out.println(Thread.currentThread().getName() + "lock:"+lockB+"=>get"+lockA); }
} } }
|
解决问题
- 使用 jps -l 定位进程号
- 使用 jstack 进程号 找到死锁问题
遇到问题,查看日志和堆栈。