我在前面的博客中写过一个生产者消费者的实现方法,只不过那篇文章用的是Object类的wait()和notify()、notifyAll().配以synchronized实现的。这篇文章将会用Reentrantlock进行同步,用condition的await()和signal、signalAll()实现等待、通知机制。
需要注意的是:
condition.await();调用后会立即失去锁,condition1.signalAll();调用后不会立即失去锁,会等待线程执行完同步(lock.lock()和lock.unlock();包围的代码)代码后失去锁。并唤醒所有(condition1.signal()只会唤醒一个)由该condition调用await()方法导致阻塞的线程。
另外 condition1.signal 和 condition1.signalAll();、condition1.signal();的调用必须保证当前线程正在持有锁,即他们必须在同步代码块中被调用。否则将会出错。
1 新建一个service类
public class MyService {
private ReentrantLock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
//一个lock可以新建多个Condition(对象监视器) 线程对象可以注册到指定的condition中
//private Condition condition2 = lock.newCondition();
private boolean flag = true;//MethodA是否可以运行 true表示可运行
public void MethodA(){
lock.lock();
if(!flag){
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产者正在执行");
this.flag = false;
condition1.signalAll();
lock.unlock();
}
public void MethodB(){
lock.lock();
if(flag){
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者正在执行");
this.flag = true;
condition1.signalAll();
lock.unlock();
}
}
2 新建一个测试类
public class Test {
public static void main(String[] args) {
MyService myService = new MyService();
Runnable runnableA = new Runnable() {
@Override
public void run() {
for(int i =0;i<10;i++){
myService.MethodA();
}
}
};
Runnable runnableB = new Runnable() {
@Override
public void run() {
for(int i =0;i<10;i++){
myService.MethodB();
}
}
};
Thread threadA = new Thread(runnableA);
Thread threadB = new Thread(runnableB);
threadB.start();
threadA.start();
}
}
运行结果:
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行
生产者正在执行
消费者正在执行