问题引出
为了更好地理解线程间的通信,可以模拟现实生活中常见的生产者消费者场景,假设有两个线程生产者线程和消费者线程,同时去操作同一种商品,其中生产者线程负责生产商品,消费者线程负责消费商品。接下来通过一个案例来实现上述情况,具体实现如文件1所示。
文件1 Example16.java
1 import java.util.*;
2 public class Example16 {
3 public static void main(String[] args) {
4 // 定义一个集合类,模拟存储生产的商品
5 List<Object> goods = new ArrayList<>();
6 // 记录线程执行前统一的起始时间start
7 long start = System.currentTimeMillis();
8 // 创建一个生产者线程,用于生产商品并存入商品集合
9 Thread thread1 = new Thread(() -> {
10 int num = 0;
11 while (System.currentTimeMillis()-start<=100) {
12 goods.add("商品" + ++num);
13 System.out.println("生产商品" + num);
14 }
15 }, "生产者");
16 // 创建一个消费线程,用于消费商品并将商品从集合删除
17 Thread thread2 = new Thread(() -> {
18 int num = 0;
19 while (System.currentTimeMillis()-start<=100) {
20 goods.remove("商品" + ++num);
21 System.out.println("消费商品" + num);
22 }
23 }, "消费者");
24 // 同时启动生产者和消费者两个线程,并统一执行100毫秒的时间
25 thread1.start();
26 thread2.start();
27 }
28 }
运行结果如图1所示。
图1 运行结果
在文件1中,简单模拟了生产者线程和消费者线程,生产者线程thread1用来生产商品并存入商品集合goods中,而消费者线程thread2用来消费商品并删除集合中的该商品,同时为了保证执行数据容易查看,控制了生产者线程和消费者线程任务的共同执行时间为100毫秒,通过在该任务执行时间内来演示多线程执行过程中出现的问题。
从图1可以看到,在两个线程任务执行起初阶段还比较正常,生产者线程一边生成商品,消费者线程一边消费商品,但是执行到后面生产者线程和消费者线程的供需节奏不一致,消费者线程一直在消耗产品而生产者线程不再生成产品,出现这种情况显然是不正确的。