多线程锁升级解决方案(JDK1.5及以后)
来源:互联网 发布:阿里云200m 编辑:程序博客网 时间:2024/06/06 03:27
在JDK1.5发布之前,我们要进行同步多线程,要使用Synchronized以及 wait notify 等对象,不够形象
如以下这个模拟生产和消费的多线程程序
class Resource{ private String name; private int count=1; private boolean flag=false; public synchronized void set(String name) { while(flag)//生产一个,消费一个 try{this.wait();}catch(Exception e){}//如果已生产则wait this.name=name+"--"+count++; System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name); flag=true;//生产之后转换状态 this.notifyAll();//唤醒所有进程,再次判断flag,故生产wait } public synchronized void out() { while(!flag) try{wait();}catch(Exception e){}//如已消费则wait System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name); flag=false;//消费之后转换状态 this.notifyAll();//唤醒所有进程,再次判断flag,故消费wait }}class Producer implements Runnable{ private Resource res; Producer(Resource res) { this.res=res; } public void run() { while(true) { res.set("+商品+");//run方法调用生产set } }}class Consumer implements Runnable{ private Resource res; Consumer(Resource res) { this.res=res; } public void run() { while(true) { res.out();//run方法调用消费out } }}public class ProducerConsumer { public static void main(String[] args) { Resource r=new Resource(); Producer pro=new Producer(r); Consumer con=new Consumer(r); Thread t1=new Thread(pro);//produce线程 Thread t2=new Thread(pro);//produce线程 Thread t3=new Thread(con);//consume线程 Thread t4=new Thread(con);//consume线程 t1.start(); t2.start(); t3.start(); t4.start(); }}
Synchronized代码执行期间,线程调用对象wait()方法,释放对象锁标志,进入等待状态,并调用notify(), notifyAll()方法通知正在等待的其他线程
这样就存在很多问题
- 如果使用notify,在有些状态下要特定唤醒某个对象,notify是唤醒wait队列第一条线程,不确定性很大
- 如果使用notifyAll,又浪费资源
- synchronized一个锁只能绑定一个对象,要依靠锁去区分对象,若加一嵌套就死锁了
1.5之后的Lock和Condition就很好地解决了这个问题
将上述代码改写之后如下
class Resource2{ private String name; private int count=1; private boolean flag=false; private Lock lock=new ReentrantLock(); private Condition condition_pro=lock.newCondition();//定义一个produce的condition private Condition condition_con=lock.newCondition();//定义一个consume的condition public void set(String name)throws InterruptedException { lock.lock(); try { while(flag)//判断状态 condition_pro.await();//如果以生产则wait this.name=name+"--"+count++; System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name); flag=true;//转换状态 condition_con.signal();//在produce里面指定唤醒consume } catch (Exception e) { } finally { lock.unlock();//用finally确保unlock,使资源得到释放 } } public void out()throws InterruptedException { lock.lock(); try { while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name); flag=false; condition_pro.signal();//在consume里面指定唤醒produce } catch (Exception e) { } finally { lock.unlock(); } }}class Producer2 implements Runnable{ private Resource res; Producer2(Resource res) { this.res=res; } public void run() { while(true) { res.set("+商品+"); } }}class Consumer2 implements Runnable{ private Resource res; Consumer2(Resource res) { this.res=res; } public void run() { while(true) { res.out(); } }}import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ProducerConsumer2 { public static void main(String[] args) { Resource r=new Resource(); Producer pro=new Producer(r); Consumer con=new Consumer(r); Thread t1=new Thread(pro); Thread t2=new Thread(pro); Thread t3=new Thread(con); Thread t4=new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); }}
- 将同步Synchronized替换成显式的Lock操作以及显式的锁对象的等待唤醒操作机制
- 一个锁可对应多个condition,预防Synchronized使用两个notify,两个锁导致形成死锁
- 将Object中的wait,notify,notifyall,封装成Condition对象 该对象可以通过Lock锁进行获取
- 该示例中,实现了本方只唤醒对方的操作。
0 0
- 多线程锁升级解决方案(JDK1.5及以后)
- 黑马程序员----JDK1.5版本中提供多线程升级解决方案
- jdk1.5以后的多线程同步方式
- jdk1.5以后的多线程同步方式
- 黑马程序员,JDK1.5中提供了多线程升级解决方案Lock操作
- JDK1.5中的多线程升级方案
- Java---20---多线程:生产者和消费者2(JDK1.5升级版)
- 黑马程序员-JDK1.5多线程安全解决方案Lock详解
- 多线程通信之优化升级+JDK1.5升级版后的新方案
- jdk1.5的多线程(非原创)
- JDK1.5以后各版本新特性
- 多线程——线程间通信{JDK1.5升级版 Lock;Conditon}
- Android Studio 升级2.3以后无法启动App的解决方案
- was ejb客户端从jdk1.5到jdk1.6升级
- jdk1.4与jdk1.5及jdk1.6的区别
- jdk1.4与jdk1.5及jdk1.6的区别
- javaweb项目jdk1.5升级1.6
- 原来是JDK1.7,新安装了JDK 1.8,以后Eclipse 打不开了解决方案
- [IO系统]01 IO子系统
- Android引导页动画的基本实现方法—ViewPager
- Laravel研究笔记一(Laravel的安装)
- ADB server didn't ACK * failed to start daemon *
- iptables 命令 源代码分析
- 多线程锁升级解决方案(JDK1.5及以后)
- 【BZOJ 2563】 阿狸和桃子的游戏 脑洞+贪心
- 计算机网络第五版谢希仁答案
- nyoj-亡命逃窜(queue函数的使用)
- 移动端调试利器
- 10420UVA 读入国家名和女人名
- Java返回泛型的方法-实例
- 【九度】题目1054:字符串内排序
- 关于卡尔曼滤波和粒子滤波最直白的解释