生产者和消费者之间的线程通讯wait()

生产者与消费者,采用notify()唤醒

package com.dwz.concurrency.chapter9;
/**
 *     生产者和消费者之间的通信问题
* 执行wait()之后锁被释放
*/ public class ProduceConsumerVersion4 { private final Object LOCK = new Object(); private int i = 0; private volatile boolean isProduced = false; private void produce() { synchronized(LOCK) { if(isProduced) { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { i++; System.out.println("p->" + i); LOCK.notify(); isProduced = true; } } } private void consumer() { synchronized(LOCK) { if(isProduced) { System.out.println("c->" + i); LOCK.notify(); isProduced = false; } else { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }

测试代码(一个生产者与一个消费者)

public static void main(String[] args) {
        ProduceConsumerVersion4 pc = new ProduceConsumerVersion4();
        
        new Thread("P") {
            @Override
            public void run() {
                while(true) {
                    pc.produce();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        
        new Thread("C") {
            @Override
            public void run() {
                while(true) {
                    pc.consumer();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

测试结果是线程安全的,程序正常结束

测试代码(多个生产者与多个消费者)

public static void main(String[] args) {
        ProduceConsumerVersion2 pc = new ProduceConsumerVersion2();
        Stream.of("P1", "P2").forEach(n -> 
            new Thread(n) {
                @Override
                public void run() {
                    while(true) {
                        pc.produce();
                    }
                }
            }.start()
        );
        
        Stream.of("C1", "C2").forEach(n ->
            new Thread(n) {
                @Override
                public void run() {
                    while(true) {
                        pc.consumer();
                    }
                }
            }.start()
        );
    }

测试结果:程序不能正常结束,被阻塞

多个生产者和多个消费者之间通信采用 notify()
缺点:会存在所有线程都等待的问题(wait)
分析:notify不能识别wait的身份,有可能消费者唤醒的是消费者,导致线程都blocked

改进方法,使用notifyAll()代替notify()

package com.dwz.concurrency.chapter9;

import java.util.stream.Stream;

/**
 *     多个生产者和多个消费者之间通信(线程安全版)
 */
public class ProduceConsumerVersion3 {
    private final Object LOCK = new Object();
    private int i = 0;
    private volatile boolean isProducted = false;
    
    private void produce() {
        synchronized(LOCK) {
            if(isProducted) {
                try {
                    LOCK.wait();
                    return;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            i++;
            System.out.println(Thread.currentThread().getName() + "for P->" + i);
            LOCK.notifyAll();
            isProducted = true;
        }
    }
    
    private void consumer() {
        synchronized(LOCK) {
            if(!isProducted) {
                try {
                    LOCK.wait();
                    return;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            
            System.out.println(Thread.currentThread().getName() + "for C->" + i);
            LOCK.notifyAll();
            isProducted = false;
        }
    }
}

测试结果,程序是线程安全的,正常执行

The difference of sleep and wait

1.sleep is the method of Thread, but wait is the method of Object
2.sleep will not release the object monitor(Lock), but the wait will be release the monitor and add to the Object monitor waiting queue
3.use sleep not need depend on monitor, but wait need
4.The sleep method not need be wakeup, but wait method need.(besides wait(milons))

原文地址:https://www.cnblogs.com/zheaven/p/12066459.html