多个线程争抢同一个monitor的lock会陷入阻塞。
看代码:
/**
* @author: wang ming xin
* @create: 2019-01-12 11:00
*/
public class ThisMonitor {
public synchronized void method1(){
System.out.println(Thread.currentThread().getName() + " enter to method1");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void method2(){
System.out.println(Thread.currentThread().getName() + " enter to method2");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
ThisMonitor monitor = new ThisMonitor();
new Thread(monitor::method1,"thread1").start();
new Thread(monitor::method2,"thread2").start();
}
}
运行结果:
thread1获取到monitor锁后,陷入沉睡
thread2阻塞
我们来用jtack命令分析下这两个线程争抢锁的情况
首先使用jps查看进程id
jstack -l 14460
很明显的看到,thread1获取了锁,并sleep
locked <0x00000000d5f8b050>
thread2 BLOCKED 阻塞
waiting to lock <0x00000000d5f8b050>
等待和线程1相同的锁
再看一个死锁的例子,并同样用jstack分析:
public class DeadLock implements Runnable {
public int flag;
private static Object o1 = new Object();
private static Object o2 = new Object();
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getName()+",flag=" + flag);
if (flag == 1) {
synchronized (o1) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (o2) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
DeadLock td1 = new DeadLock();
DeadLock td2 = new DeadLock();
td1.flag = 1;
td2.flag = 0;
new Thread(td1,"thread1").start();
new Thread(td2,"thread2").start();
}
}
运行结果:
jstack分析:
自己需要获取的锁被对方持有,
对方需要获取的锁被自己持有,
导致死锁
说点什么
您将是第一位评论人!