线程间的通信——生产者消费者问题
【题目一】
- 用两个线程操作初始值为0的资源类,一个线程进行加操作,另一个线程进行减操作:
【思路】
- 线程、操作、资源类
- 判断、干活、通知(synchronized)
【代码】
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareDataOne//资源类
{
private int number = 0;//初始值为零的一个变量
public synchronized void increment() throws InterruptedException
{
//1判断
if(number !=0 ) {
this.wait();
}
//2干活
++number;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//3通知
this.notifyAll();
}
public synchronized void decrement() throws InterruptedException
{
// 1判断
if (number == 0) {
this.wait();
}
// 2干活
--number;
System.out.println(Thread.currentThread().getName() + "\t" + number);
// 3通知
this.notifyAll();
}
}
public class NotifyWaitDemoOne
{
public static void main(String[] args)
{
ShareDataOne sd = new ShareDataOne();
new Thread(() -> {
//线程一
for (int i = 1; i < 10; i++) {
try {
sd.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "A").start();
new Thread(() -> {
//线程二
for (int i = 1; i < 10; i++) {
try {
sd.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "B").start();
}
}
【题目二】
- 在【题目一】的基础上改为多个线程进行加操作,多个线程进行减操作:
【思路】
- 继续使用if语句判断会造成spurious weakup(虚假唤醒),使用while循环可以将等待的线程重新进行判断
【代码】
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.omg.IOP.Codec;
class ShareData//资源类
{
private int number = 0;//初始值为零的一个变量
public synchronized void increment() throws InterruptedException
{
//判断
while(number!=0) {
this.wait();
}
//干活
++number;
System.out.println(Thread.currentThread().getName()+" \t "+number);
//通知
this.notifyAll();