java实现:《操作系统实验二》使用notify,wait方法实现三个线程的锁死及三种解决方法

使用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();
	}
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45273552/article/details/109234806