Java synchronized 实现生产者-消费者模型

synchronized

synchronized (临界资源) {
	// 访问临界资源的代码
}

上述代码的作用是给临界资源“加锁”,其他线程访问临界资源会被阻塞,目的是保证同一时间只有一个线程访问临界区。

wait

临界资源.wait();

某个线程调用了临界资源的wait方法后,该线程被阻塞,直到被其他线程唤醒才能继续执行。

notify

临界资源.notify();

某个线程执行该方法后,随机唤醒一个试图访问临界区但处于阻塞状态的线程。

完整代码 demo.java

import java.util.LinkedList;
import java.util.Queue;

public class demo {
    Queue<Integer> 临界资源 = new LinkedList<>();
    final int MAX = 10;

    public static void main(String[] args) {
        demo d = new demo();
        生产者 producer = d.new 生产者();
        消费者 consumer = d.new 消费者();
        producer.start();
        consumer.start();
    }

    class 生产者 extends Thread {
        @Override
        public void run() {
            while (true) { // 每隔0.5s生产一个商品
                synchronized (临界资源) { // 临界资源被占用,其他线程访问临界资源将被阻塞
                    while (临界资源.size() == MAX) { // 临界区已满,唤醒消费者线程,阻塞生产者线程,此处不用 if 是为了保险
                        临界资源.notify(); // 唤醒试图访问临界资源的阻塞线程
                        System.out.println("临界区已满");
                        try {
                            临界资源.wait(); // 阻塞当前线程,等待其他线程唤醒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    临界资源.add(1); // 生产一个商品
                    临界资源.notify(); // 唤醒消费者
                    System.out.println("已生产1件商品,当前商品数量:" + 临界资源.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    class 消费者 extends Thread {
        @Override
        public void run() {
            while (true) { // 每隔0.5秒消耗一个商品
                synchronized (临界资源) {
                    while (临界资源.size() == 0) { // 资源耗尽
                        临界资源.notify();
                        System.out.println("临界资源耗尽");
                        try {
                            临界资源.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    临界资源.poll(); // 消耗一个商品
                    临界资源.notify(); // 唤醒生产者
                    System.out.println("已消耗1件商品,当前商品数量:" + 临界资源.size());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}



发布了105 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Kwansy/article/details/104127502
今日推荐