例子:
class Test implements Runnable{
private boolean flag;
Test(boolean flag) {
this.flag = flag;
}
public void run(){
if (flag){
synchronized (MyLock.locka){
System.out.println("if.....locka....");
synchronized(MyLock.lockb){
System.out.println("if.....lockb....");
}
}
}
else{
synchronized (MyLock.lockb){
System.out.println("else.....lockb....");
synchronized(MyLock.locka){
System.out.println("else.....locka....");
}
}
}
}
}
class MyLock {
public static final Object locka = new Object();
public static final Object lockb = new Object();
}
public class Demo{
public static void main(String[] args){
Test a = new Test(true);
Test b = new Test(false);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
}
}
由main主线线程开始执行
Test a = new Test(true);
Test b = new Test(false);
然后再把它们的地址分别给到 t1
t2
创建的Thread对象中
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
如果不给的话
t1.start();
t2.start();
执行的就是默认的run,毫无意义…
.
.
.
.
.
主线程main执行
Test a = new Test(true);
Test b = new Test(false);
使得它们两个的flag
的标记都是不一样的,a是true
, b是false
接着main主线程继续往下走,直到开启两个线程
t1.start();
t2.start();
这时候,t1是a的true
cpu也刚好在执行它,于是就进入到了
if (flag){
synchronized (MyLock.locka){
System.out.println("if.....locka....");
synchronized(MyLock.lockb){
System.out.println("if.....lockb....");
}
}
}
拿到了MyLock.locka
的锁
也就是public static final Object locka = new Object();
输出了if.....locka....
这时候cpu突然不执行t1线程了,去执行t2线程了
(因为cpu是随机执行的!!!)
因为第二个是fals所以执行这个
else{
synchronized (MyLock.lockb){
System.out.println("else.....lockb....");
synchronized(MyLock.locka){
System.out.println("else.....locka....");
}
}
}
这时候拿到了MyLock.lockb
的锁
也就是public static final Object lockb = new Object();
然后执行输出:else.....lockb....
这时要进入 synchronized(MyLock.locka)
语句,发现锁已经被t1的拿了,就这样一直反反复复进不去…
一直到cpu重新随机到t1
线程要执行synchronized(MyLock.lockb)
语句,但是synchronized(MyLock.lockb)
语句已经被t2拿了
这时候t1反反复复进不去…
.
.
一直到cpu重新随机到t2,就这样反反复复谁也拿不到,进不去…导致了多线程的死锁
有时候也会是t2先抢到CPU的执行权…但是结果都是一样的出不去,进不来…
就是输出不一样而已…
有些人也有可能可以执行成功,但那只是在理想状态…可以在哪里加个循环试一下,迟早会发生死锁…
运行效果图(1):
这种是t1先抢到cpu的执行权
这样不会往下走了…
.
.
.
.
.
运行效果图(2):
这种是t2先抢到cpu的执行权
这样也不会往下走了…