java 生产者和消费者例子(wait,notify)

点击链接加入群聊【java菜鸟学习】:https://jq.qq.com/?_wv=1027&k=5afU7nS
群号:124569404

  • 通过wait notify 第一种(比较啰嗦)
public class ProduceConsumeVersion2 {

    public static void main(String[] args) {
        ProduceConsumeVersion2 p = new ProduceConsumeVersion2();
        new Thread(() -> {
            while (true) {
                p.produce();
            }
        }, "produce").start();

        new Thread(() -> {
            while (true) {
                p.consume();
            }
        }, "consume").start();
    }

    private static Integer i = 0; //生产的数字
    private static boolean flgProduce = false; //生产状态
    private static Object obj = new Object(); 


    public static void produce() {
        synchronized (obj) {
            if (flgProduce) {
                try {
               		//生产了数字但是没有被消费,等待消费者消费
                    obj.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                //没有生产数字
                //生产一个数字,通知消费者消费
                i++;
                System.out.println("produce i:" + i);
                try {
                    obj.notify();
                    //设置生产状态为已生产
                    flgProduce = true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }

    public static void consume() {
        synchronized (obj) {
            if (flgProduce) {
            	//可消费,模拟消费
                System.out.println("consume i:" + i);
                try {
                	//消费完成之后通知生产者继续生成数字
                    obj.notify();
                    //将生产状态改为未生成
                    flgProduce = false;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
            	//没有可消费的数字
                try {
                	//等待生产者进行生产
                    obj.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

  • 通过wait notify 第二种(简化代码,使用了线程池技术)

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ClassName: WaitAndNotify
 *
 * @author leegoo
 * @Description:
 * @date 2019年05月23日
 */
public class WaitAndNotify {

    private static Object object = new Object();
    private static volatile AtomicInteger number = new AtomicInteger(1);
    private static volatile AtomicBoolean flg = new AtomicBoolean(false);


    public static void main(String[] args) throws  Exception{

        ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("demo-thread-%d").build();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024), factory);
        executor.execute(()->{
            try {
                WaitAndNotify.provider();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        executor.execute(()->{
            try {
                WaitAndNotify.consume();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    public static void provider() throws Exception {
        while (true) {
            synchronized (object) {
                if (!flg.get()) {
                    number.getAndIncrement();
                    int numberAndIncrement = number.get();
                    System.out.println(Thread.currentThread().getName()+"生成了数字:" + numberAndIncrement);
                    Thread.sleep(1_000);
                    flg.getAndSet(true);
                    object.wait();
                }
            }

        }
    }


    public static void consume() throws Exception {
        while (true) {
            synchronized (object) {
                if (flg.get()) {
                    int number = WaitAndNotify.number.get();
                    System.out.println(Thread.currentThread().getName() + "消费了数字:" + number);
                    Thread.sleep(1_000);
                    flg.getAndSet(false);
                    object.notify();
                }

            }
        }
    }
}
  • 使用阻塞队列
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ClassName: WaitAndNotify2
 *
 * @author leegoo
 * @Description:
 * @date 2019年05月23日
 */
public class WaitAndNotify2 {


    private static volatile AtomicInteger number = new AtomicInteger(0);

    private static volatile BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(1, true);

    public static void provider() {
        while (true) {
            int numb = number.incrementAndGet();
            System.out.println(Thread.currentThread().getName() + "生成了数字:" + numb);
            try {
                blockingQueue.put(numb);
                Thread.sleep(1_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }


    public static void consumer() {
        while (true) {
            Integer getNumber = null;
            try {
                getNumber = blockingQueue.take();
                System.out.println(Thread.currentThread().getName() + "消费了数字:" + getNumber);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("demo-thread-%d").build();
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(2, 3, 50, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), factory);
        poolExecutor.execute(() -> consumer());
        poolExecutor.execute(() -> provider());
    }

}

代码上传地址:
https://github.com/q920447939/java-study/blob/master/java-base/src/main/java/thread/WaitAndNotify.java
https://github.com/q920447939/java-study/blob/master/java-base/src/main/java/thread/WaitAndNotify2.java

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值