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

生产者与消费者,采用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;
        }
    }
}

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

猜你喜欢

转载自www.cnblogs.com/zheaven/p/12066459.html