模拟生产者和消费者

1、使用“多线程&锁”模拟生产者和消费者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class ShareData {
    private int number = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
 
    public void increment() throws Exception {
        lock.lock();
        try {
            //多线程的判断必须要用while
            while (number != 0) {
                //释放当前锁,进入等待状态,不能生产
                //唤醒线程从await()返回后需要重新获得锁
                condition.await();
            }
            //生产
            number++;
            System.out.println(Thread.currentThread().getName() + "\t" + number);
            //通知唤醒所有等待线程
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
 
    public void decrement() throws Exception {
        lock.lock();
        try {
            //多线程的判断必须要用while
            while (number != 1) {
                //释放当前锁,进入等待状态,不能消费
                //唤醒线程从await()返回后需要重新获得锁
                condition.await();
            }
            //消费
            number--;
            System.out.println(Thread.currentThread().getName() + "\t" + number);
            //通知唤醒所哟等待线程
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
 
public class ProducerConsumer {
    public static void main(String[] args) {
        ShareData shareData = new ShareData();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    shareData.increment();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();
 
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    shareData.decrement();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();
    }
}

2、使用“多线程&阻塞队列”模拟生产者和消费者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
class ShareResource {
    //默认开启,进行生产+消费
    private volatile boolean FLAG = true;
    private AtomicInteger atomicInteger = new AtomicInteger();
 
    BlockingQueue<String> blockingQueue = null;
 
    public ShareResource(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
        System.out.println(blockingQueue.getClass().getName());
    }
 
    public void produce() throws InterruptedException {
        String data = null;
        boolean retValue;
        while (FLAG) {
            data = atomicInteger.incrementAndGet() + "";
            retValue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
            if (retValue) {
                System.out.println(Thread.currentThread().getName() + "\t 插入队列" + data + "成功");
            } else {
                System.out.println(Thread.currentThread().getName() + "\t 插入队列" + data + "失败");
            }
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println(Thread.currentThread().getName() + "\tFLAG=false,生产结束");
    }
 
    public void consume() throws InterruptedException {
        String data = null;
        while (FLAG) {
            data = blockingQueue.poll(2L, TimeUnit.SECONDS);
            if (null == data || data.equalsIgnoreCase("")) {
                FLAG = false;
                System.out.println(Thread.currentThread().getName() + "\t 超过2秒钟没有取到数据,消费退出");
                System.out.println();
                return;
            }
            System.out.println(Thread.currentThread().getName() + "\t消费数据" + data + "成功");
        }
    }
 
    public void stop() {
        this.FLAG = false;
    }
}
 
public class ProducerAndConsumer {
 
    public static void main(String[] args) throws InterruptedException {
        ShareResource shareResource = new ShareResource(new ArrayBlockingQueue<String>(10));
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "生产线程启动");
            try {
                shareResource.produce();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Producer").start();
 
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "消费线程启动");
            try {
                shareResource.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Consumer").start();
 
        TimeUnit.SECONDS.sleep(5);
        System.out.println("5秒钟时间到,活动结束");
 
        shareResource.stop();
    }
}

  

posted @   达摩克利斯之剑  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示