传统生产消费者模式例子
这里写的是传统版还有一版是阻塞队列版,这里的例子可以和阻塞队列版对比。下面我们来做一道小需求题“一个初始值为零的变量,两个线程对其交替操作,一个加1一个减1,执行5次”。
代码如下:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareData {//资源类
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment() throws Exception {
lock.lock();
try {
//1 判断
while (number != 0) {
//等待,不能生产
condition.await();
}
//2干活
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number);
//3通知唤醒
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrement() throws Exception {
lock.lock();
try {
//1 判断
while (number == 0) {
//等待,不能生产
condition.await();
}
//2干活
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number);
//3通知唤醒
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 一个初始值为零的变量,两个线程对其交替操作,一个加1一个减1,执行5次
*/
public class ConsumerTraditionDemo {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareData.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"t1").start();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareData.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"t2").start();
}
}
运行结果:

这里需要注意为什么用while而不用if因为用while可以防止虚假唤醒机制。
这里改下代码演示如下:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareData {//资源类
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment() throws Exception {
lock.lock();
try {
//1 判断
if (number != 0) {
//等待,不能生产
condition.await();
}
//2干活
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number);
//3通知唤醒
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrement() throws Exception {
lock.lock();
try {
//1 判断
if (number == 0) {
//等待,不能生产
condition.await();
}
//2干活
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number);
//3通知唤醒
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 一个初始值为零的变量,两个线程对其交替操作,一个加1一个减1,执行5次
*/
public class ConsumerTraditionDemo {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareData.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"t1").start();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareData.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"t2").start();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareData.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"t3").start();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareData.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"t4").start();
}
}
运行结果:

修改if为while后运行如下:

997

被折叠的 条评论
为什么被折叠?



