public class ThreadTest02 {//演示程序死锁
public static void main(String[] args) {
StringBuffer stringBuffer1 = new StringBuffer();
StringBuffer stringBuffer2 = new StringBuffer();
new Thread(){
//为什么这里需要使用内部类? 需要使用父类或接口的某个方法,这里是需要创建线程,父类是Thread,只需要使用一次,后面不再使用
//如何使用用匿名内部类? 直接new实现的接口或继承的父类,在括号里重写接口或父类的方法
//创建线程的方式一是当前类继承 Thread 类重写 run方法
//Thread对象或Thread对象的子类调start()方法来开启线程
@Override
public void run() {
synchronized (stringBuffer1){//stringBuffer1
stringBuffer1.append("1");
stringBuffer2.append("a");
//如果不添加阻塞,不会出现死锁
//这里出现死锁的原因:
//线程1调用完stringBuffer1进入阻塞,在阻塞期间线程2会去调用stringBuffer2,然后线程2进入阻塞
//当线程1阻塞结束去调用stringBuffer2,此时stringBuffer2被线程2占用,线程2同理调用stringBuffer1被线程1占用
//于是就形成了死锁,双方线程都占用对方需要的同步资源不放弃,并且等待对方放弃自己需要的同步资源
try {
Thread.sleep(100);//阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (stringBuffer2){//stringBuffer2
stringBuffer1.append("2");
stringBuffer2.append("b");
}
System.out.println(stringBuffer1);
System.out.println(stringBuffer2);
}
}
}.start();
new Thread(new Runnable() {//使用匿名内部类完成 实现Runnable接口重写run方法 创建线程
@Override
public void run() {
synchronized (stringBuffer2){//stringBuffer2
stringBuffer1.append("3");
stringBuffer2.append("c");
try {
Thread.sleep(100);//阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (stringBuffer1){//stringBuffer1
stringBuffer1.append("4");
stringBuffer2.append("d");
}
System.out.println(stringBuffer1);
System.out.println(stringBuffer2);
}
}
}).start();
}
}
使用匿名内部类创建线程演示程序死锁
最新推荐文章于 2022-02-23 16:50:17 发布