学习笔记——JAVA线程<5>线程的死锁
来源:互联网 发布:25岁衣服品牌知乎 编辑:程序博客网 时间:2024/06/05 04:50
死锁:过多的同步容易造成死锁
使用同一份资源谁都不放手就锁住了
模拟死锁
package study;/** * 模拟死锁 * @author http://blog.csdn.net/thewaiting/ * */public class ThreadDome { public static void main(String[] args) { Object goods = new Object(); Object money = new Object(); Test t1 = new Test(goods, money); Test2 t2 = new Test2(goods, money); Thread proxy = new Thread(t1); Thread proxy2 = new Thread(t2); proxy.start(); proxy2.start(); }}class Test implements Runnable { Object goods = new Object(); Object money = new Object(); public Test(Object goods, Object money) { super(); this.goods = goods; this.money = money; } @Override public void run() { while (true) { test(); } } private void test() { synchronized (goods) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (money) { } } System.out.println("给钱"); }}class Test2 implements Runnable { Object goods; Object money; public Test2(Object goods, Object money) { this.goods = goods; this.money = money; } @Override public void run() { while (true) { test(); } } private void test() { synchronized (money) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (goods) { } } System.out.println("给货"); }}
生产者消费者(也成有限缓冲问题)模式解决死锁
先生产 后消费
生产者在缓冲区满时休眠(要么干脆放弃数据)等到下次消费者消耗缓冲区的数据的时候,生产者才能被唤醒开始往缓冲区添加数据。
消费者在缓冲区空时休眠,等到生产者往缓冲区添加数据再唤醒消费者。
通常的方法:信号灯法,管程等
如果解决方法不够完善则容易出现死锁情况
出现死锁时连个线程都会陷入休眠,等待对方唤醒自己
首先模拟一下
package study;//测试public class Text { public static void main(String[] args) { //共同的资源 ThreadDome2 t = new ThreadDome2(); //多线程 同时使用资源t Production p = new Production(t); Consume c = new Consume(t); new Thread(p).start(); new Thread(c).start(); }}运行结果生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产 生产
package study;/** * * @author http://blog.csdn.net/thewaiting/ * */public class ThreadDome2 { private String resource; public void production(String resource) { this.resource =resource; } public void consume() { System.out.print(resource+" "); }}/** * 生产者 * @author http://blog.csdn.net/thewaiting/ * */class Production implements Runnable{ private ThreadDome2 t;//资源 public Production(ThreadDome2 t) { super(); this.t = t; } @Override public void run() { for (int i = 0; i < 20; i++) { if (0==i%2) { t.production("生产/被2整除"); }else { t.production("生产"); } } }}/** * 消费者 * @author http://blog.csdn.net/thewaiting/ * */class Consume implements Runnable{ private ThreadDome2 t; public Consume(ThreadDome2 t) { super(); this.t = t; } @Override public void run() { for (int i = 0; i < 20; i++) { t.consume(); } }}
信号灯法
唤醒:
notify() 唤醒在此对象监视器上等待的单个线程
notifyAll() 唤醒在此对象监视器上等待的所有线程
等待:
wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。等待会释放锁sleep()不是释放锁*
以上方法要与同步一起使用,没有同步则无法等待
修改ThreadDome2 代码
package study;/** * 使用生产者消费者模式 * 信号灯法 * @author http://blog.csdn.net/thewaiting/ * */public class ThreadDome2 { private String resource; //信号灯 //当flag为true时生产者生产,消费者等待,生产完成后通知消费者 //当flag为false消费者时生产,生产者等待,消费完成后通知生产者 private boolean flag = true; public synchronized void production(String resource) throws InterruptedException { if (!flag) {//生产者等待 this.wait(); } //开始生产 Thread.sleep(500);//模拟生产时间 放大错误的概率 //生产完毕 this.resource =resource; //通知消费 this.notify(); //生产者停下 this.flag = false; } public synchronized void consume() throws InterruptedException { if (flag) {//消费者等待 this.wait(); } //开始消费 Thread.sleep(200);//模拟消费时间 放大错误的概率 System.out.print(resource+" "); //消费完毕 //通知生产者 this.notify(); //消费停止 this.flag = true; }}运行结果生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产 生产/被2整除 生产
阅读全文
0 0
- 学习笔记——JAVA线程<5>线程的死锁
- Java学习笔记之线程(四):线程的死锁现象
- Java 线程同步与死锁 学习笔记
- java线程——死锁
- java线程——死锁
- Java——线程死锁
- 学习笔记——JAVA线程<2>线程的状态
- 学习笔记——JAVA线程<3>线程的基本信息
- 学习笔记——JAVA线程<4>线程的同步
- 学习笔记——JAVA线程<7>线程的总结
- 线程学习笔记(九)-死锁
- Java笔记六.线程同步、线程死锁
- Java菜鸟学习笔记--多线程篇(三):线程死锁
- 线程学习6——死锁
- 8、学习线程——死锁
- [线程]——死锁
- java再复习——线程的死锁问题
- 线程学习(二)——线程同步,死锁
- spark性能优化:数据倾斜调优
- 一入科协似海深,从此装逼成路人
- 页面置换算法
- Linux基本命令
- GET 和 POST 有什么区别?
- 学习笔记——JAVA线程<5>线程的死锁
- day06 面向对象基础
- JDBC之PreparedStatement
- usacoP1827 美国血统 American Heritage(递归&&二分&&树)
- Linux学习 iscsi
- SDUT 3928 C~K玩游戏
- Android—布局
- 精通Dubbo——dubbo2.0源码中Spring Bean的加载
- 菜鸟小白的人生中第一篇博客