死锁的产生以及如何防止死锁的产生
2016-06-03 21:17
274 查看
不多说,先来看一个例子:
class Car{ Exception c; private boolean waxOn=false;//waxOn表示的是正在打蜡。 public synchronized void waxed(){//当打蜡完成的时候,就将抛光的线程唤醒 waxOn=true; notifyAll(); } public synchronized void buffed(){//表示抛光的动作已经完成了,又将打蜡的线程唤醒 waxOn=false; notifyAll(); } public synchronized void waitForWaxing() {//这个表示的是线程在灯光打蜡的动作完成 while (waxOn = false) { try { wait();//这里的话,表示的是一直等待,知道别人把这个给唤醒 } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void waitForBuffing() {//这里表示的是等待抛光的动作完成 while (waxOn = true) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } //这个表示的是抛光的过程 class WaxOn implements Runnable{ private Car car; public WaxOn(Car car) { this.car=car; } @Override public void run() { try { while (!Thread.interrupted()) { System.out.println("Wax on"); TimeUnit.MILLISECONDS.sleep(200); car.waxed(); car.waitForBuffing(); } } catch (InterruptedException e) { System.out.println("Exiting via interrupt"); } System.out.println("Ending Wax Off task"); } } //这个表示的是打蜡完成,抛光的过程 class WaxOff implements Runnable{ private Car car; public WaxOff(Car car) { this.car=car; } @Override public void run() { try { while (!Thread.interrupted()) { car.waitForWaxing();//这个表示的是在抛光之前必须等待打蜡过程的完成。 System.out.println("Wax off");//表示的是打蜡过程完成了 TimeUnit.MILLISECONDS.sleep(200);//这个表示的是抛光所需要的时间 car.buffed();//这个表示的是正在抛光 } } catch (InterruptedException e) { System.out.println("Exiting via interrupt"); } System.out.println("Ending Wax off task"); } }
public class WaxOMatic { } public static void main(String[] args){ Car car=new Car(); ExecutorService exec= Executors.newCachedThreadPool(); exec.execute(new WaxOff(car)); exec.execute(new WaxOn(car)); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } exec.shutdownNow(); } }以下的这个例子也是一样的,只是使用了不同的方法而已:
class WaxOn implements Runnable{//这是涂蜡任务 WaxOMatic waxOMatic; public WaxOn(WaxOMatic waxOMatic) { this.waxOMatic=waxOMatic; } @Override public void run() { try { while (!Thread.interrupted()) { synchronized (this) { while (!waxOMatic.flag) {//flag为false的时候,表示的是正在等待。 wait(); } } System.out.println("这俩车正在打蜡"); waxOMatic.flag=false; synchronized (waxOMatic.waxOff) { waxOMatic.waxOff.notifyAll(); } } } catch (InterruptedException e) { e.printStackTrace(); } } } class WaxOff implements Runnable{//这是抛光任务 private WaxOMatic waxOMatic; public WaxOff(WaxOMatic waxOMatic) { this.waxOMatic=waxOMatic; } @Override public void run() { try { while (!Thread.interrupted()) { synchronized (this) { while (waxOMatic.flag) { wait(); } } System.out.println("这俩车正在抛光"); waxOMatic.flag=true; synchronized (waxOMatic.waxOn) { waxOMatic.waxOn.notifyAll(); } } } catch (InterruptedException e) { e.printStackTrace(); } } }public class WaxOMatic {
WaxOn waxOn = new WaxOn(this);
WaxOff waxOff = new WaxOff(this);
boolean flag=true;
ExecutorService exec= Executors.newCachedThreadPool();
public WaxOMatic() {
exec.execute(waxOn);
exec.execute(waxOff);
}
public static void main(String[] args){
new WaxOMatic();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
}
程序的输出的结果为:
这俩车正在打蜡 这俩车正在抛光 这俩车正在打蜡 这俩车正在抛光
我们再来看一下另外一种形式的代码:
/*这个程序主要处理的是汽车的打蜡和抛光的任务*/ class Car{ //只是一个标志 boolean flag=true; //表示的是正在涂蜡 public synchronized void WaxOn() { try { while (!Thread.interrupted()) { synchronized (this) { while (!flag) { wait(); } } System.out.println(Thread.currentThread().getName()+"正在打蜡"); TimeUnit.MILLISECONDS.sleep(500);//表示的是打蜡需要的时间 notifyAll(); flag=false;//打蜡完成以后,需要等待抛光完成了以后,才能继续完成下一次的打蜡。因此需要等待 } } catch (InterruptedException e) { e.printStackTrace(); } } //表示的是正在抛光 public synchronized void buff() { try { while (!Thread.interrupted()) { synchronized (this) { while (flag) { wait(); } } System.out.println(Thread.currentThread().getName()+"正在抛光"); TimeUnit.MILLISECONDS.sleep(500);//表示的是抛光需要的时间 notifyAll(); flag=true; } } catch (InterruptedException e) { e.printStackTrace(); } } } class WaxOn implements Runnable{ private Car car;//关联上的是同一份的资源 public WaxOn(Car car) { this.car=car; } @Override public void run() { car.WaxOn(); } } class Buff implements Runnable{ private Car car; public Buff(Car car) { this.car=car; } @Override public void run() { car.buff(); } } public class WaxOMatic{ public static void main(String[] args){ Car car=new Car(); ExecutorService exec= Executors.newCachedThreadPool(); WaxOn waxOn = new WaxOn(car); Buff buff = new Buff(car); for(int i=0;i<5;i++){ exec.execute(waxOn); exec.execute(buff); } try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.exit(0); } }
最后的输出的结果为:
pool-1-thread-1正在打蜡 pool-1-thread-10正在抛光 pool-1-thread-9正在打蜡 pool-1-thread-6正在抛光 pool-1-thread-7正在打蜡 pool-1-thread-4正在抛光 pool-1-thread-3正在打蜡 pool-1-thread-2正在抛光 pool-1-thread-3正在打蜡 pool-1-thread-4正在抛光 pool-1-thread-5正在打蜡 pool-1-thread-6正在抛光 pool-1-thread-9正在打蜡 pool-1-thread-8正在抛光 pool-1-thread-1正在打蜡 pool-1-thread-10正在抛光 pool-1-thread-9正在打蜡 pool-1-thread-6正在抛光 pool-1-thread-7正在打蜡 pool-1-thread-4正在抛光
现在我们再来看一看使用显式的lock和condition是如何实现防止死锁的产生的。
class Car { //只是一个标志 boolean flag = true; private Lock lock = new ReentrantLock(); private Condition condition=lock.newCondition(); //表示的是正在涂蜡 /*注意在这个方法中,由于是使用了显式的Lock和condition,那么就不能使用synchronized了,这是要注意的 * 也就是不能这样写:public void waxOn,否则是打不开的*/ public void WaxOn() { try { while (!Thread.interrupted()) { lock.lock(); try { while (!flag) { condition.await(); } } finally { lock.unlock(); } System.out.println("正在打蜡"); TimeUnit.MILLISECONDS.sleep(500); // notifyAll(); condition.signalAll(); flag = false;//打蜡完成以后,需要等待抛光完成了以后,才能继续完成下一次的打蜡。因此需要等待 } } catch (InterruptedException e) { e.printStackTrace(); } } //表示的是正在抛光 public void buff() { try { while (!Thread.interrupted()) { //使用显式的Lock lock.lock(); try { while (flag) { condition.await(); } } finally { lock.unlock(); } System.out.println("正在抛光"); TimeUnit.MILLISECONDS.sleep(500); // notifyAll(); //一般来说,使用这个condition.signalAll()的话,比使用notifyAll()更好,效率更高 condition.signalAll(); flag = true; } } catch (InterruptedException e) { e.printStackTrace(); } }
} class WaxOn implements Runnable{ private Car car;//关联上的是同一份的资源 public WaxOn(Car car) { this.car=car; } @Override public void run() { car.WaxOn(); } } class Buff implements Runnable{ private Car car; public Buff(Car car) { this.car=car; } @Override public void run() { car.buff(); } } public class WaxOMatic{ public static void main(String[] args){ Car car=new Car(); ExecutorService exec= Executors.newCachedThreadPool(); WaxOn waxOn = new WaxOn(car); Buff buff = new Buff(car); exec.execute(waxOn); exec.execute(buff); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.exit(0); } }最后的输出的结果为:
正在打蜡 正在抛光 正在打蜡 正在抛光 正在打蜡 正在抛光
其实为了防止唤醒自己的同类,那么我们可以使用不同的condition来进行处理:
/*我们来看看如何利用显示的Lock和Condition来防止这种情况的发生*/ class Car { //只是一个标志 boolean flag = true; private Lock lock = new ReentrantLock(); //可以使用不同的condition来处理,这样的话,可以避免唤醒自己的同类。其实,在线程中,队列也是这样实现的。 private Condition condition=lock.newCondition(); private Condition condition2=lock.newCondition(); //表示的是正在涂蜡 //注意在这个方法中,不能再使用synchronized,否则是不正确的 //也就是不能写为public synchronized void waxOn public void WaxOn() { try { while (!Thread.interrupted()) { lock.lock(); try { while (!flag) { condition.await(); } System.out.println("正在打蜡"); condition2.signal(); flag = false; // notifyAll(); TimeUnit.MILLISECONDS.sleep(500); //打蜡完成以后,需要等待抛光完成了以后,才能继续完成下一次的打蜡。因此需要等待 } finally { lock.unlock(); } } } catch (InterruptedException e) { e.printStackTrace(); } } //表示的是正在抛光 public void buff() { try { while (!Thread.interrupted()) { //使用显式的Lock lock.lock(); try { while (flag) { condition2.await(); } System.out.println("正在抛光"); // notifyAll(); //一般来说,使用这个condition.signalAll()的话,比使用notifyAll()更好,效率更高 condition.signal(); flag = true; TimeUnit.MILLISECONDS.sleep(500); } finally { lock.unlock(); } } } catch (InterruptedException e) { e.printStackTrace(); } } } class WaxOn implements Runnable{ private Car car;//关联上的是同一份的资源 public WaxOn(Car car) { this.car=car; } @Override public void run() { car.WaxOn(); } } class Buff implements Runnable{ private Car car; public Buff(Car car) { this.car=car; } @Override public void run() { car.buff(); } } public class WaxOMatic{ public static void main(String[] args){ Car car=new Car(); ExecutorService exec= Executors.newCachedThreadPool(); WaxOn waxOn = new WaxOn(car); Buff buff = new Buff(car); exec.execute(waxOn); exec.execute(buff); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.exit(0); }
其实,代码都是差不多的,只是改了其中的一点点。最后输出的结果也是一样的。
相关文章推荐
- 矩阵顺时针旋转90度
- 第二阶段冲刺第十天
- poj 3204(最小割--关键割边)
- Windows7+VS2012下OpenGL 4的环境配置
- hdu2044 一只小蜜蜂....
- [Ruby笔记]22.Ruby :: namespace 以及 instance method 与class method
- 华为项目管理10大模板Excel版(可直接套用_非常实用)
- js-shortid:优雅简洁地实现短ID
- 阿里云Hadoop开发自动打包上传运行maven的pom.xml
- c++作业7
- 第116课: Spark Streaming性能优化:如何在毫秒内处理处理大吞吐量的和数据波动比较大 的程序
- Android Studio常用快捷键、Android Studio快捷键大全
- 浪潮之巅 科技之巅
- 个人最终总结
- storm集群搭建
- https相关原理
- 查找两个数组的公共元素
- 观察者模式
- linux socket 编程
- 读软件工程的职业道德有感