通过Lock对象以及Condition对象实现多线程同步
2014-10-07 21:20
531 查看
在之前的学习中,无论是通过synchronized建立同步代码块,还是通过synchronized建立同步函数,都是把对象看成一把锁来实现同步,这种解释有点牵强,而且在消费者—生产者的那个实例中,其实还有个问题,那就是在避免线程全部冻结时,没必要把相同功能的线程解冻,只要把其他功能的线程解冻即可,也就是说消费者线程只要解冻生产者线程即可,没必要把其他消费者线程也解冻,为了解决这些问题,java1.5版本推出了同步的升级办法,那就是通过Lock对象和Condition对象实现同步。
新的同步办法不再需要synchronized关键字,而引入了更加形象的Lock。
Lock实质上是是一个接口,在创建对象时,使用Lock的子类ReentrantLock来建立对象。
使用方法:建立对象后,在需要同步的代码前一行写 Lock对象.lock(); ,在同步代码后一行写 Lock对象.unlock();
Lock对象用来控制线程的进出,而对线程的操作则由Condition对象来操作;
对应关系:
wait——await(两者均抛出异常)
notify——signal
notifyAll——signalAll
Condition同样是接口,建立方法(比较神奇) Condition 对象名=Lock对象.newCondition();
API上的解释:
Condition对象的优势在于,signal只能唤醒被相同Condition对象的await方法冻结的线程,因此,可以建立多个Condition对象,分别用来冻结和解冻不同功能的线程
最后要注意的是,Lock接口属于类包java.util.concurrent.locks,因此,在写代码前,应该先导入类包
上次实例的升级版:
新的同步办法不再需要synchronized关键字,而引入了更加形象的Lock。
Lock实质上是是一个接口,在创建对象时,使用Lock的子类ReentrantLock来建立对象。
使用方法:建立对象后,在需要同步的代码前一行写 Lock对象.lock(); ,在同步代码后一行写 Lock对象.unlock();
Lock对象用来控制线程的进出,而对线程的操作则由Condition对象来操作;
对应关系:
wait——await(两者均抛出异常)
notify——signal
notifyAll——signalAll
Condition同样是接口,建立方法(比较神奇) Condition 对象名=Lock对象.newCondition();
API上的解释:
Condition实例实质上被绑定到一个锁上。要为特定
Lock实例获得
Condition实例,请使用其
newCondition()方法。
Condition对象的优势在于,signal只能唤醒被相同Condition对象的await方法冻结的线程,因此,可以建立多个Condition对象,分别用来冻结和解冻不同功能的线程
最后要注意的是,Lock接口属于类包java.util.concurrent.locks,因此,在写代码前,应该先导入类包
上次实例的升级版:
//需求:产品每生产一个消费一个 import java.util.concurrent.locks.*; class ProducerConsumerDemo { 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(); } } class Resource { private String name; private int count = 1; private boolean flag = false; Lock lock=new ReentrantLock(); Condition pro = lock.newCondition(); Condition con = lock.newCondition(); public void set(String name) { lock.lock(); while(flag) try{pro.await();}catch(Exception e){} this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name); flag = true; con.signalAll(); lock.unlock(); } public void out() { lock.lock(); while(!flag) try{con.await();}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name); flag = false; pro.signalAll(); lock.unlock(); } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) { res.set("+商品+"); } } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while(true) { res.out(); } } }注意看Resource类的变化
相关文章推荐
- 通过Lock对象以及Condition对象实现多线程同步
- salesforce 零基础学习(三十六)通过Process Builder以及Apex代码实现锁定记录( Lock Record)
- 基于Lock对象的Condition接口实现的有界队列
- Object 监视器方法分解成截然不同的对象, 以便通过将这些对象与任意Lock 实现组合使用,为每个对象提供多个等待 set
- Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信
- asp.net通过反射技术实现Ajax(2)--前台javascript封装的Ajax对象
- TAO教程之四:改进服务端之通过POA策略实现持久化的对象引用
- 在.Net中通过序列化和反序列化实现对象实例化
- 华为AR28-31通过单臂路由实现vlan间路由以及介入Internet 推荐
- 通过渲染到纹理和32位浮点纹理实现三维对象选取
- 通过实现接口 ICloneable 复制对象
- 通过序列化和反序列化泛型数据实体集合来实现持久化数据对象的方法
- 编程如禅——工厂模式的智能化实现(c++)(2)消灭switch/case语句以及由名字创建对象
- jQuery.API源码深入剖析以及应用实现(2) - jQuery对象访问和数据缓存
- jQuery.API源码深入剖析以及应用实现(2) - jQuery对象访问和数据缓存
- jQuery.API源码深入剖析以及应用实现(2) - jQuery对象访问和数据缓存
- 通过Action对象实现任意代码片断的统一异常处理
- 对象间通信方法之一:通过委托实现(C#语言)
- (六)线程--分别用lock以及Interlocked和Monitor类实现线程的临界区操作(互斥)(示例下载)
- (六)线程--分别用lock以及Interlocked和Monitor类实现线程的临界区操作(互斥)(示例下载)