美文网首页JAVA自我总结
线程通信-wait(notify)

线程通信-wait(notify)

作者: Coderlifesunny | 来源:发表于2019-01-29 10:56 被阅读0次

    知识总结

    多线程通信最经典的模型就是生产者消费者模式,java中有队列LinkedList可以实现该模式,做到通信协议。

    wait和notify(notifyAll)是所有对象的公共方法。

    wait和notify必须在同步关键字synchronized代码块中使用。

    notify是唤醒应wait等待而进入wait-set集合队列中的队首的线程,notifyALL是唤醒集合队列中所有的线程,然后所有线程任然要同步竞争synchronized(Object)的monitor。

    wait与sleep均可以使线程阻塞,sleep只能是线程调用(线程 的方法)。

    wait会释放monitor锁,sleep会一直持有。

    wait可以不设置等待时间,sleep必须设置等待时间。

    撸代码尝试

    @Data
    @Slf4j
    public class EventQueue {
    
        private static final int DEFAULT_MAX_EVENT = 10;
    
        private int max;
    
        private final LinkedList<Event> eventQueue = new LinkedList<>();
    
        @Data
        @ToString
        @NoArgsConstructor
        @AllArgsConstructor
        static class Event {
            private String ele;
        }
    
        public EventQueue() {
            this(DEFAULT_MAX_EVENT);
        }
    
        public EventQueue(int max) {
            this.max = max;
        }
    
        /**
         * 往队列里面放数据
         */
        public void offer(Event ele) {
            synchronized (eventQueue) {
                try {
                    while (eventQueue.size() >= max) {
                        log.warn("队列已满,请稍后再试试~");
                        eventQueue.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                eventQueue.addLast(ele);
                eventQueue.notifyAll();
                log.info("size:" + eventQueue.size() + "成功添加元素:" + ele.getEle());
            }
        }
    
        /**
         * 取队列元素
         *
         * @return
         */
        public Event take() {
            synchronized (eventQueue) {
                try {
                    while (eventQueue.isEmpty()) {
                        log.warn("队列为空,请稍后再试~");
                        eventQueue.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Event event = eventQueue.removeFirst();
                eventQueue.notifyAll();
                log.info("size:" + eventQueue.size() + "成功取出元素:" + event.getEle());
                return event;
            }
        }
    
        public static void main(String[] args) {
            EventQueue queue = new EventQueue();
            new Thread(() -> {
                for (int i = 0; i < Integer.MAX_VALUE; ++i) {
                    queue.offer(new Event(String.valueOf(i)));
                }
            }, "Product").start();
    
            new Thread(() -> {
                for (; ; ) {
                    queue.take();
    
                    try {
                        TimeUnit.MILLISECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "Consumer").start();
        }
    
    
    }
    

    相关文章

      网友评论

        本文标题:线程通信-wait(notify)

        本文链接:https://www.haomeiwen.com/subject/adatsqtx.html