在同步机制中,至少存在两个线程的时候,如果它们相互占用了对方所需要的锁对象,那么就会出现死锁现象,因为它们都在等待对方的资源释放后才能继续执行自己的程序。为了避免死锁现象发生,我们一般不在同步代码块中嵌套同步代码块。
死锁示例:
package lianxi;
public class SiSuo extendsThread{
publicSiSuo(String arg0) {//为了在创建线程对象时设置线程的名字,重写父类的有参构造方法
super(arg0);
}
publicvoid run(){
Strings1 = "左筷子";//创建锁对象一,万物皆对象,可以是String类对象
Strings2 = "右筷子";//创建锁对象二
while(true){
if(Thread.currentThread().getName().equals("张三")){//第一个线程执行if代码块,先占有第一个锁对象,再嵌套占有第二个锁对象
synchronized(s1){
System.out.println(Thread.currentThread().getName()+"占有左筷,需要右筷");
synchronized(s2){
System.out.println(Thread.currentThread().getName()+"占有两双筷子");
}
}
}else{//第二个线程执行else代码块,先占有s2锁对象,再占有s1代码块
try{
/*设置先让第二个代码块睡眠1秒钟,这样可以让第一个线程先执行一段时间,
* 然后第二个线程再执行时方便看得出在第二个线程执行之前第一个线程曾经
* 占有过两个锁对象,在第二个线程开始执行后,占有了第二个锁对象,此时就会出现死锁现象。*/
Thread.currentThread().sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(s2){
System.out.println(Thread.currentThread().getName()+"占有右筷子,需要左筷子");
synchronized(s1){
System.out.println("占有两双筷子");
}
}
}
}
}
}
package lianxi;
public class Lianxi13 {
publicstatic void main(String[] args) {
//死锁
Threadt1 = new SiSuo("张三");
Threadt2 = new SiSuo("李四");
t1.start();
t2.start();
}
}
运行结果:
张三线程在执行时占有左筷子,还没有占有右筷子时,李四线程开始执行,占有了右筷子,会这样就导致死锁现象的发生。