前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >生产者&消费者

生产者&消费者

原创
作者头像
HLee
修改2021-10-19 10:03:59
8260
修改2021-10-19 10:03:59
举报
文章被收录于专栏:房东的猫房东的猫

wait&notify

wait方法的作用是使当前正在执行的线程进入等待状态,wait方法是Object类的方法,该方法用来将当前线程放入到“预执行队列”中,并且在wait所在的代码行进行停止执行,直到接到通知或被中断为止。在调用wait方法之前,线程必须获得该对象的对象锁,也就是说只能在同步方法或同步代码块中调用wait方法。在执行wait方法后,当前线程锁会自动释放,当wait方法返回该线程与其他线程重新竞争获取锁。

notify方法也是要在同步方法或者同步代码块中使用,在调用前必须获得对象的对象锁。这个方式是用来通知那些可能等待锁对象的其他线程,如果有多个线程等待,由线程调试器随机选一个wait状态的线程,向其发出通知,并使等待获取该对象的对象锁。

在执行notify方法后,当前线程不会马上释放该对象的对象锁,wait状态的线程也不能马上获取该对象的对象锁,要等到执行notify方法的线程将任务执行完成后,也就是退出synchronized代码块后,当前线程才会释放锁,wait状态的线程才可以获得锁。

一生产者一消费者

代码语言:javascript
复制
public class ThreadTest30 {

    public static void main(String[] args) {

        ThreadVo threadVo = new ThreadVo();

        Thread producer = new ThreadProducer(threadVo);
        producer.setName("生产者");
        producer.start();

        Thread consumer = new ThreadConsumer(threadVo);
        consumer.setName("消费者");
        consumer.start();
    }
}

class ThreadProducer extends Thread{

    private ThreadVo threadVo;

    public ThreadProducer(ThreadVo threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) { 
            threadVo.push(Math.random() + "");
        }
    }
}

class ThreadConsumer extends Thread{

    private ThreadVo threadVo;

    public ThreadConsumer(ThreadVo threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            if (list.size() == 1) {
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName() + "添加数据");
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            this.notify();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            if (list.size() == 0) {
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName() + ": 消费数据: " + returnVal);
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            this.notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

执行结果:
生产者添加数据
生产者: 还有:1个数据
生产者等待中
消费者: 消费数据: 0.6627895017650591
消费者: 还有:0个数据
消费者等待中
生产者添加数据
生产者: 还有:1个数据
......

一生产者多消费者

代码语言:javascript
复制
public class ThreadTest31 {

    public static void main(String[] args) {

        ThreadVo31 threadVo = new ThreadVo31();

        Thread producer = new ThreadProducer31(threadVo);
        producer.setName("生产者");
        producer.start();

        Thread[] consumers = new Thread[5];
        for (int i = 0; i < consumers.length; i++) {
            consumers[i] = new ThreadConsumer31(threadVo);
            consumers[i].setName("消费者" + (char)('A' + i));
            consumers[i].start();
        }
    }
}

class ThreadProducer31 extends Thread{

    private ThreadVo31 threadVo;

    public ThreadProducer31(ThreadVo31 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.push(Math.random() + "");
        }
    }
}

class ThreadConsumer31 extends Thread{

    private ThreadVo31 threadVo;

    public ThreadConsumer31(ThreadVo31 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo31 {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            if (list.size() == 1) {
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName() + "添加数据");
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            this.notify();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            while (list.size() == 0) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName() + ": 消费数据: " + returnVal);
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            // 唤醒全部生产者
            this.notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

多生产者一消费者

代码语言:javascript
复制
public class ThreadTest32 {

    public static void main(String[] args) {

        ThreadVo32 threadVo = new ThreadVo32();

        Thread[] producsers = new Thread[5];
        for (int i = 0; i < producsers.length; i++) {
            producsers[i] = new ThreadProducer32(threadVo);
            producsers[i].setName("生产者" + (char)('A' + i));
            producsers[i].start();
        }

        Thread consumer = new ThreadConsumer32(threadVo);
        consumer.setName("消费者");
        consumer.start();
    }
}

class ThreadProducer32 extends Thread{

    private ThreadVo32 threadVo;

    public ThreadProducer32(ThreadVo32 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.push(Math.random() + "");
        }
    }
}

class ThreadConsumer32 extends Thread{

    private ThreadVo32 threadVo;

    public ThreadConsumer32(ThreadVo32 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo32 {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            while (list.size() == 1) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName() + "添加数据");
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            this.notifyAll();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            while (list.size() == 0) {
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName() + ": 消费数据: " + returnVal);
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            // 唤醒全部生产者
            this.notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

多生产者多消费者

代码语言:javascript
复制
public class ThreadTest33 {

    public static void main(String[] args) {

        ThreadVo33 threadVo = new ThreadVo33();

        Thread[] producsers = new Thread[5];
        Thread[] consumers = new Thread[5];
        for (int i = 0; i < producsers.length; i++) {
            producsers[i] = new ThreadProducer33(threadVo);
            producsers[i].setName("生产者" + (char)('A' + i));
            producsers[i].start();

            consumers[i] = new ThreadConsumer33(threadVo);
            consumers[i].setName("消费者" + (char)('A' + i));
            consumers[i].start();
        }
    }
}

class ThreadProducer33 extends Thread{

    private ThreadVo33 threadVo;

    public ThreadProducer33(ThreadVo33 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.push(Math.random() + "");
        }
    }
}

class ThreadConsumer33 extends Thread{

    private ThreadVo33 threadVo;

    public ThreadConsumer33(ThreadVo33 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo33 {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            while (list.size() == 1) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName() + "添加数据");
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            this.notifyAll();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            while (list.size() == 0) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName() + "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName() + ": 消费数据: " + returnVal);
            System.out.println(Thread.currentThread().getName() + ": 还有:" + list.size() + "个数据");
            // 唤醒全部生产者
            this.notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • wait&notify
    • 一生产者一消费者
      • 一生产者多消费者
        • 多生产者一消费者
          • 多生产者多消费者
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档