在jdk1.5中,多了一个新包java.util.concurrent,在这个包下面有关于线程操作的接口和类。这里主要用到了Lock和Condition。
package fighting;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadProducerConsumer2 {
/**
* 生产者-消费者的例子用jdk5.0改写实现:
* Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
*
* jdk1.5中提供了多线程的升级解决方案:
* Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法(wait,notify,notifyAll)的使用。
* Condition对象可以通过lock对象获取。
* 在该实例中,实现了本方只唤醒对方的操作。即生产者唤醒消费者,消费者唤醒生产者。
* 一个锁,可以对应多个Conditon,唤醒不同线程。参考①②
*/
public static void main(String[] args) {
Resource1 res=new Resource1();
new Thread(new Producer(res)).start();
new Thread(new Producer(res)).start();
new Thread(new Consumer(res)).start();
new Thread(new Consumer(res)).start();//如果是多个线程消费,就有可能发生,生产者生产一个,不同消费者消费同一个产品的情况;
//或者生产者生产两次,消费者只消费了一次。
}
}
class Resource2{
private String name;
private int count = 1;
private boolean flag=false;
private Lock lock=new ReentrantLock();
// private Condition condition = lock.newCondition();
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newCondition();
public void set(String name) throws InterruptedException{
lock.lock();
try{
while(flag){
// condition.await();
condition_pro.await();//①生产者等待
}
this.name=name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);
flag=true;
// condition.signalAll();
condition_con.signal();//②消费者唤醒
}finally{
lock.unlock();
}
}
public void out() throws InterruptedException{
lock.lock();
try{
while(!flag){
// condition.await();
condition_con.await();//②消费者等待
}
System.out.println(Thread.currentThread().getName()+"...消费者"+this.name);
flag=false;
// condition.signalAll();
condition_pro.signal();//①生产者唤醒
}finally{
lock.unlock();
}
}
}
class Producer2 implements Runnable{
private Resource2 res;
Producer2(Resource2 res){
this.res=res;
}
public void run(){
while(true){
try {
res.set("商品");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer2 implements Runnable{
private Resource2 res;
Consumer2(Resource2 res){
this.res=res;
}
public void run(){
while(true){
try {
res.out();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}