一、两个线程生产者消费者
/**
* @Author: cy
* @Date: 2021/09/24/14:12
* 题目:现在两个线程,可以操作初始值为零的一个变量
* 实现一个线程对该变量加1,一个线程对该变量减1
* 实现交替,来10轮,变量初始值为零
*
* 1、 高内聚低耦合前提下,线程操作资源类
* 2、 判定/干活/通知
* 3、 多线程交互中,必须要防止多线程的虚假唤醒,也即(判断只用while,不能用if)
*/
class AirConditioner{
//资源类
private int number = 0;
//加一操作
public synchronized void increment() throws InterruptedException {
//1.判定 如果为1则该线程等待 并释放锁
if(number != 0){
this.wait();
}
//2.不为0则 干活
number++;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3.干完活通知唤醒其他线程
this.notifyAll();
}
//减一操作
public synchronized void decrement() throws InterruptedException {
//1.判定 如果为0则该线程等待 并释放锁
if(number != 1){
this.wait();
}
//2.不为0则 干活
number--;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3.干完活通知唤醒其他线程
this.notifyAll();
}
}
public class ThreadWaitNotifyDemo {
public static void main(String[] args) {
AirConditioner airConditioner = new AirConditioner();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
}
}
输出:
A 1
B 0
A 1
B 0
A 1
B 0
.....
两个线程用if不会发送虚假唤醒
二、四个线程生产者消费者
class AirConditioner{
//资源类
private int number = 0;
//加一操作
public synchronized void increment() throws InterruptedException {
//1.判定 如果为1则该线程等待 并释放锁
while (number != 0){
this.wait();
}
//2.不为0则 干活
number++;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3.干完活通知唤醒其他线程
this.notifyAll();
}
//减一操作
public synchronized void decrement() throws InterruptedException {
//1.判定 如果为0则该线程等待 并释放锁
while (number != 1){
this.wait();
}
//2.不为0则 干活
number--;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3.干完活通知唤醒其他线程
this.notifyAll();
}
}
public class ThreadWaitNotifyDemo {
public static void main(String[] args) {
AirConditioner airConditioner = new AirConditioner();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
此时必须把if判定改为while
三、JUC生产者消费者
/**
* @Author: cy
* @Date: 2021/09/24/14:12
* 题目:现在两个线程,可以操作初始值为零的一个变量
* 实现一个线程对该变量加1,一个线程对该变量减1
* 实现交替,来10轮,变量初始值为零
*
* 1、 高内聚低耦合前提下,线程操作资源类
* 2、 判定/干活/通知
* 3、 多线程交互中,必须要防止多线程的虚假唤醒,也即(判断只用while,不能用if)
*/
class AirConditioner2{
//资源类
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//加一操作
public void increment() throws InterruptedException {
lock.lock();
try {
//1.判定 如果为1则该线程等待 并释放锁
while (number != 0){
condition.await();
}
//2.不为0则 干活
number++;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3.干完活通知唤醒其他线程
condition.signalAll();
} finally {
lock.unlock();
}
}
//减一操作
public synchronized void decrement() throws InterruptedException {
lock.lock();
try {
//1.判定 如果为0则该线程等待 并释放锁
while (number != 1){
condition.await();
}
//2.不为0则 干活
number--;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3.干完活通知唤醒其他线程
condition.signalAll();
} finally {
lock.unlock();
}
}
}
public class ThreadWaitNotifyDemo2 {
public static void main(String[] args) {
AirConditioner2 airConditioner = new AirConditioner2();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
airConditioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}