使用notify,wait方法实现三个线程的锁死及三种解决方法
public class DeadLock4 {
public static void main(String[] args) {
StringBuffer s1=new StringBuffer();//StringBuffer是线程安全类,以此作为锁
StringBuffer s2=new StringBuffer();
StringBuffer s3=new StringBuffer();
//线程一
new Thread() {
public void run() {
int count=100;
while(count>0) {
synchronized(s1) {
try {
s1.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count--;
System.out.println(count);
synchronized(s2) {
s2.notify();
}
}
}
}.start();
//线程二
new Thread() {
public void run() {
int count=100;
while(count>0) {
synchronized(s2) {
try {
s2.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count--;
System.out.println(count);
synchronized(s3) {
s3.notify();
}
}
}
}.start();
//线程三
new Thread() {
public void run() {
int count=100;
while(count>0) {
synchronized(s3) {
try {
s3.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count--;
System.out.println(count);
synchronized(s1) {
s1.notify();
}
}
}
}.start();
}
}
运行结果:
产生死锁原因:
线程1释放s1锁,进入准备池(准备池中线程一不再进行线程调度权的竞争),此时线程执行权由线程2或线程3拿到,线程执行await方法,释放s2锁,同样进入准备池,线程3拿到线程执行权执行await方法,同样释放s3
锁,进入准备池,此时锁池(线程在锁池中才能进行线程执行权的竞争)已经没有线程,程序进入死锁。
解决方式一:
在主线程中手动进行线程的唤醒。
如下代码:
//解决方式一
synchronized(s2) {
s2.notifyAll();
}
使用notifyAll方法唤醒准备池中所有线程,使其进入锁池进行线程执行权的竞争。
运行结果:
执行成功!
解决方式二:
限制锁的阻塞时间
在三个线程中的wait方法中增加时间参数,如下:
运行结果:
解决方式三:
使用Semaphore线程同步辅助类代替synchronized同步代码块,以其参数控制同时访问资源的线程个数。
参考代码:
import java.util.concurrent.Semaphore;
public class DeadLock {
public static void main(String[] args) {
Semaphore s1=new Semaphore(1);
Semaphore s2=new Semaphore(0);
Semaphore s3=new Semaphore(0);
//线程一
new Thread() {
public void run() {
int count=100;
while(count>0) {
try {
s1.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count--;
System.out.println(count);
s2.release();
}
}
}.start();
//线程二
new Thread() {
public void run() {
int count=100;
while(count>0) {
try {
s2.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count--;
System.out.println(count);
s3.release();
}
}
}.start();
//线程三
new Thread() {
public void run() {
int count=100;
while(count>0) {
try {
s3.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count--;
System.out.println(count);
s1.release();
}
}
}.start();
}
}
运行结果: