示例:分别创建并启动五个线性用于生产鸡蛋,消费鸡蛋;且鸡蛋最多可以有10个,消费鸡蛋只能是生产好了的鸡蛋,完成一边生产鸡蛋,一边消费鸡蛋的模型。
创建一个鸡蛋资源类EggRes,该类中封装有鸡蛋个数count,行为有生产鸡蛋,消费鸡蛋两个方法,
用同步锁来解决同步问题,等待唤醒机制完成线程间通讯,正常完成多生产多消费功能实现;
鸡蛋资源类EggRes代码如下:
class EggRes {
//最多能同时存在鸡蛋10个
int count;
boolean flag = true;
public void product() {
//鸡蛋小于10个时,生产鸡蛋线程为唤醒状态;鸡蛋为10个以上时,等待状态;
while (true) {
//执行while循环目的是使该线程可以生产很多鸡蛋,而不是生产一个鸡蛋就执行结束了
if (count >= 10) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + ",生产了鸡蛋:" + ++count );
//每次生产一次鸡蛋,该线程就释放出锁,给予其他生产线程,消费线程竞争锁的机会
try {
wait(3000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//此时,消费线程肯定为唤醒状态,那么唤醒所有线程
notifyAll();
}
}
public void consumer() {
//鸡蛋大于0个时,消费鸡蛋线程为唤醒状态; 鸡蛋为0时,等待状态
while (true) {
if (count <= 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//模拟消费鸡蛋需要耗时2s,这里线程没有释放出锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + ",消费了鸡蛋:" + count--);
//每次消费一次鸡蛋,该线程就释放出锁,给予其他生产线程,消费线程竞争锁的机会
try {
wait(3000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//此时,生产线性必须为唤醒状态,唤醒全部线程
notifyAll();
}
}
}
//生产线程
class MyProductThread extends Thread {
private EggRes er;
public MyProductThread(EggRes er) {
this.er = er;
}
@Override
public void run() {
synchronized (er){
er.product();
}
}
}
//消费线程
class MyConsumerThread extends Thread {
private EggRes er;
public MyConsumerThread(EggRes er) {
this.er = er;
}
@Override
public void run() {
synchronized (er) {
er.consumer();
}
}
}
public class MulProduct2Consumer {
public static void main(String[] args) {
//生产线程,消费线程的共享资源类EggRes
EggRes er = new EggRes();
MyProductThread[] mpts = new MyProductThread[5];
for (int i = 0; i < mpts.length; i++) {
mpts[i] = new MyProductThread(er);
mpts[i].start();
}
MyConsumerThread[] mcts = new MyConsumerThread[5];
for (int i = 0; i < mcts.length; i++) {
mcts[i] = new MyConsumerThread(er);
mcts[i].start();
}
}
}
public class MulProduct2Consumer {
public static void main(String[] args) {
//生产线程,消费线程的共享资源类EggRes
EggRes er = new EggRes();
MyProductThread[] mpts = new MyProductThread[5];
for (int i = 0; i < mpts.length; i++) {
mpts[i] = new MyProductThread(er);
mpts[i].start();
}
MyConsumerThread[] mcts = new MyConsumerThread[5];
for (int i = 0; i < mcts.length; i++) {
mcts[i] = new MyConsumerThread(er);
mcts[i].start();
}
}
}
//鸡蛋类
class EggRes {
//最多能同时存在鸡蛋10个
int count;
boolean flag = true;
public void product() {
//鸡蛋小于10个时,生产鸡蛋线程为唤醒状态;鸡蛋为10个以上时,等待状态;
while (true) {
//执行while循环目的是使该线程可以生产很多鸡蛋,而不是生产一个鸡蛋就执行结束了
if (count >= 10) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + ",生产了鸡蛋:" + ++count );
//每次生产一次鸡蛋,该线程就释放出锁,给予其他生产线程,消费线程竞争锁的机会
try {
wait(3000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//此时,消费线程肯定为唤醒状态,那么唤醒所有线程
notifyAll();
}
}
public void consumer() {
//鸡蛋大于0个时,消费鸡蛋线程为唤醒状态; 鸡蛋为0时,等待状态
while (true) {
if (count <= 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//模拟消费鸡蛋需要耗时2s,这里线程没有释放出锁
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + ",消费了鸡蛋:" + count--);
//每次消费一次鸡蛋,该线程就释放出锁,给予其他生产线程,消费线程竞争锁的机会
try {
wait(3000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//此时,生产线性必须为唤醒状态,唤醒全部线程
notifyAll();
}
}
}
//生产线程
class MyProductThread extends Thread {
private EggRes er;
public MyProductThread(EggRes er) {
this.er = er;
}
@Override
public void run() {
synchronized (er){
er.product();
}
}
}
//消费线程
class MyConsumerThread extends Thread {
private EggRes er;
public MyConsumerThread(EggRes er) {
this.er = er;
}
@Override
public void run() {
synchronized (er) {
er.consumer();
}
}
}
截取部分打印结果:
线程Thread-3,生产了鸡蛋:1
线程Thread-5,消费了鸡蛋: 1
线程Thread-4,生产了鸡蛋:1
线程Thread-2,生产了鸡蛋:2
线程Thread-1,生产了鸡蛋:3
线程Thread-4,生产了鸡蛋:4
线程Thread-5,消费了鸡蛋: 4
线程Thread-3,生产了鸡蛋:4
线程Thread-9,消费了鸡蛋: 4
线程Thread-0,生产了鸡蛋:4
线程Thread-9,消费了鸡蛋: 4
线程Thread-3,生产了鸡蛋:4
线程Thread-5,消费了鸡蛋: 4
线程Thread-4,生产了鸡蛋:4
线程Thread-1,生产了鸡蛋:5
线程Thread-2,生产了鸡蛋:6
线程Thread-8,消费了鸡蛋: 6
线程Thread-6,消费了鸡蛋: 5
线程Thread-7,消费了鸡蛋: 4
线程Thread-8,消费了鸡蛋: 3