码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程-生产者/消费者模式实现

时间:2020-03-18 23:56:02      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:void   count()   interrupt   tin   obj   java   not   img   简单   

单生产者与单消费者

示例:

public class ProduceConsume {
        public static void main(String[] args) {
            String lock = new String("");
            Produce produce = new Produce(lock);
            Consume consume = new Consume(lock);

            new Thread(() -> {
                while (true) {
                    produce.setValue();
                }
            }, "ProductThread").start();
            new Thread(() -> {
                while (true) {
                    consume.getValue();
                }
            }, "ConsumeThread").start();
        }

        /**
         * 生产者
         */
        static class Produce {
            private String lock;

            public Produce(String lock) {
                this.lock = lock;
            }

            public void setValue() {
                try {
                    synchronized (lock) {
                        if (!ValueObject.value.equals("")) {
                            lock.wait();
                        }
                        String value = System.currentTimeMillis() + "_" + System.nanoTime();
                        System.out.println("set的值是" + value);
                        ValueObject.value = value;
                        lock.notify();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 消费者
         */
        static class Consume {
            private String lock;

            public Consume(String lock) {
                this.lock = lock;
            }

            public void getValue() {
                try {
                    synchronized (lock) {
                        if (ValueObject.value.equals("")) {
                            lock.wait();
                        }
                        System.out.println("get的值是" + ValueObject.value);
                        ValueObject.value = "";
                        lock.notify();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        static class ValueObject {
            public static String value = "";
        }
}

执行结果如下:

技术图片

 

 

多生产者与多消费者

这种模式下,容易出现“假死”,也就是全部线程都进入了 WAITNG 状态,程序不在执行任何业务功能了,整个项目呈停止状态。

示例:

public class MultiProduceConsume {
    public static void main(String[] args) throws InterruptedException {
        String lock = new String("");
        Produce produce = new Produce(lock);
        Consume consume = new Consume(lock);
        Thread[] pThread = new Thread[2];
        Thread[] cThread = new Thread[2];
        for (int i = 0; i < 2; i++) {
            pThread[i] = new Thread(() -> {
                while (true) {
                    produce.setValue();
                }
            }, "生产者" + (i + 1));

            cThread[i] = new Thread(() -> {
                while (true) {
                    consume.getValue();
                }
            }, "消费者" + (i + 1));
            pThread[i].start();
            cThread[i].start();
        }

        Thread.sleep(5000);
        Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];
        Thread.currentThread().getThreadGroup().enumerate(threadArray);
        for (int i = 0; i < threadArray.length; i++) {
            System.out.println(threadArray[i].getName() + " " + threadArray[i].getState());
        }
    }

    static class Produce {
        private String lock;

        public Produce(String lock) {
            this.lock = lock;
        }

        public void setValue() {
            try {
                synchronized (lock) {
                    while(!ValueObject.value.equals("")) {
                        System.out.println("生产者 " + Thread.currentThread().getName() + " WAITING了?");
                        lock.wait();
                    }
                    System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了");
                    String value = System.currentTimeMillis() + "_" + System.nanoTime();
                    ValueObject.value = value;
                    lock.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Consume {
        private String lock;

        public Consume(String lock) {
            this.lock = lock;
        }

        public void getValue() {
            try {
                synchronized (lock) {
                    while (ValueObject.value.equals("")) {
                        System.out.println("消费者 " + Thread.currentThread().getName() + " WAITING了?");
                        lock.wait();
                    }
                    System.out.println("消费者 " + Thread.currentThread().getName() + "RUNNABLE了");
                    ValueObject.value = "";
                    lock.notify();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class ValueObject {
        public static String value = "";
    }
}

运行结果如图:

技术图片

 

分析:

虽然代码中通过 wait/notify 进行通信了,但是不能保证 notify 唤醒的一定是异类,也可能是同类,比如“生产者”唤醒了“生产者”这样的情况。

解决方案:

假死出现的主要原因是有可能连续唤醒了同类。所以解决方案很简单,就是把 notify() 改为 notifyAll() 即可。

Java多线程-生产者/消费者模式实现

标签:void   count()   interrupt   tin   obj   java   not   img   简单   

原文地址:https://www.cnblogs.com/lkc9/p/12521091.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!