相对与从前苦逼的同步机制,Java 5 出现了更优化更直观的 Lock 和 Condition 两个新机制可以用,并且一个 Lock 可以对应多个 Condition,从而允许不一样的等待和唤醒机制。
package thread;
import java.util.concurrent.locks.*;
/*
该对象可以Lock锁 进行获取。该示例中,实现了本方只唤醒对方操作。
JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify notifyAll,替换成Condition对象。
Lock类的官方解释:
实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。
此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。
Condition的官方解释:
将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,
以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。
其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
Lock:替代了Synchronized
lock
unlock
newCondition()
Condition:替代了Object 的 wait notify notifyAll
await();
signal();
signalAll();
*/
public class Thread_6_ProducerConsumerDemo3 {
public static void main(String[] args)
{
Resource2 r = new Resource2();
Producer2 pro = new Producer2(r);
Consumer2 con = new Consumer2(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 Resource2{
private String name;
private int count = 1;
private boolean flag = false;
//建立一个锁,舍弃了之前直接拿res对象做锁的方法
//相对与从前的将某个对象或类视作“锁”的策略
//Lock类直接将“锁”这个概念明朗化了
private Lock lock = new ReentrantLock();
//同一个lock上可以由多个相关的condition
//被A condition叫去wait的线程,只能由A conditon唤醒
//避免了同步块嵌套导致死锁的危险
private Condition AAAAAA = lock.newCondition();
private Condition BBBBBB = lock.newCondition();
public void set(String name)
{
lock.lock(); //同步块开始
try{
while(flag)
AAAAAA.await(); //如果仓库已满,生产者被 A 叫去等待
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
//生产完毕,所有消费者被 B 唤醒
BBBBBB.signalAll();
}catch(Exception e){
e.printStackTrace();
}finally{
//finally块里面一般放的都是释放资源的动作
//同步块结束,释放锁的动作必须执行
lock.unlock();
}
}
public void out()
{
lock.lock(); //同步块开始
try{
while(!flag)
BBBBBB.await(); //如果仓库已空,消费者被 B 叫去等待
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
AAAAAA.signalAll(); //
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock(); //同步块结束
}
}
}
class Producer2 implements Runnable{
private Resource2 res;
Producer2(Resource2 res){
this.res = res;
}
public void run(){
while(true) {
res.set("+商品+");
}
}
}
class Consumer2 implements Runnable{
private Resource2 res;
Consumer2(Resource2 r){
this.res = r;
}
public void run(){
while(true){
res.out();
}
}
}