包括synchronized和ReetrantLock
可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁
synchronized版本
public class demo1 { public static void main(String[] args) { Phone phone=new Phone(); new Thread(()->{ phone.sms(); },"A").start(); new Thread(()->{ phone.call(); },"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"); } }
ReentrantLock版本
public class demo2 { public static void main(String[] args) { Phone2 phone=new Phone2(); new Thread(()->{ phone.sms(); },"A").start(); new Thread(()->{ phone.call(); },"B").start(); } } class Phone2{ Lock lock=new ReentrantLock(); public synchronized void sms(){ lock.lock(); try { System.out.println(Thread.currentThread().getName()+" sms"); call();//这里再次获得了对象锁,而没有出现死锁 } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } public synchronized void call(){ lock.lock();//锁必须配对,加了锁就要解锁 try { System.out.println(Thread.currentThread().getName()+" call"); } catch (Exception e) { e.printStackTrace(); }finally { lock.unlock(); } } }
自旋锁
/** * @author *min * @create 2021-07-11-13:40 * @description * T1先进来拿到锁,期望是null,变成了thread,这时候T2拿到锁后为thread 开始自旋(阻塞), * 等待T1变会null,T2走出自旋 */ public class test { public static void main(String[] args) throws InterruptedException { demo3 demo=new demo3(); new Thread(()->{ demo.myLock(); try { TimeUnit.SECONDS.sleep(2); } catch (Exception e) { e.printStackTrace(); }finally { demo.myUnlock(); } },"T1").start(); TimeUnit.SECONDS.sleep(1);//让T1一定能先抢到锁 new Thread(()->{ demo.myLock(); try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) { e.printStackTrace(); }finally { demo.myUnlock(); } },"T2").start(); } }
死锁
public class deadLock { 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 lock1; private String lock2; public MyThread(String lockA,String lockB){ this.lock1=lockA; this.lock2=lockB; } @SneakyThrows @Override public void run() { synchronized (lock1){ //线程进来了拿到了1锁,然后又想要去拿2锁 System.out.println(Thread.currentThread().getName()+" lock:"+lock1+"want get=>"+lock2); TimeUnit.SECONDS.sleep(2); synchronized (lock2){ System.out.println("造成死锁"); } } }
如何排查送死锁
使用java bin目录下的工具
首先是查看进程号7112
通过此命令查看死锁
发现死锁