Java并发编程之生产者与消费者-----synchronized实现+企业级模板

一.问题引入

两个线程,操作一个初始值为0的变量:

  • 一个线程对变量加一
  • 一个线程对变量减一
  • 实现交替操作十轮

二.编程模板

在高内聚,低耦合的前提下,线程-------->操作--------->资源类

  • 高内聚低耦合:在这个条件下,指的是对变量的改变(增加和减少等操作),都是在变量内部进行,比如这个问题中,要对变量加一减一,这两个方法都是在变量的内部进行,外部线程只是调用而已
  • 线程:这个不用解释了把
  • 操作:线程通过变量内部的方法,即变量暴露给外界可调用的方法来对变量进行操作
  • 资源类:将变量设置为一个类。

三.代码怎么写

模板:判断------>干活------>通知

class shareData{ //线程共享的资源类

    private  int number = 0;

    public synchronized void  increment() throws InterruptedException {

        //1.判断 此时共享资源如果不是0 那么不生产
        while(number != 0){
            this.wait();
        }

        //2.干活
        number++;
        System.out.println(Thread.currentThread().getName()+"\t当前个数"+number);

        //3.通知
        this.notifyAll();
    }

    public synchronized void decrement() throws InterruptedException {

        //1.判断 此时共享资源如果是0那么不消费 等待
        while(number == 0){
            this.wait();
        }

        //2.干活
        number--;
        System.out.println(Thread.currentThread().getName()+"\t当前个数"+number);

        //3.通知
        this.notifyAll();
    }

}
  1. 这个类中首先要定义我们的共享变量number。初始化值为0
  2. 然后写increment()方法,这个方法要对我们的资源类进行操作,因为结果要实现1-0-1-0这样的交替变化,所以同一时间我们只能有一个线程进行增加,故为方法加上synchronized 关键字
  3. 第一步,判断:我们的increment是对变量进行增加的方法,也就是生产者,为了得到想要的结果,我们要考虑当前number的值,假如number值为1,那么我们就不能加了,需要阻塞,只有当number为0,我们才能生产
  4. 判断用if可以吗?答案是不行 多线程交互中,要防止线程的虚假唤醒,也即(判断只用while 不用if)用if判断当下一个时间片轮转到该线程时,该线程的记录点可能已经在if条件判断之后了,故此该次执行会从if语句后开始执行 —>要用while让线程重新判断 这个地方我们只有两个的情况下没问题,但如果有多个生产者和消费者就会出现2,3,等结果
  5. 第二步:干活,我们是生产者所以number++,然后打印一下
  6. 第三步:通知,我们的工作结束了,唤醒阻塞在这个资源类对象的其他线程。

四.结果

public static void main(String[] args) {
        shareData shareData = new shareData();

        new Thread(()->{
            for (int i = 1 ; i<= 10 ; i++){
                try {
                    shareData.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"producer01").start();

        new Thread(()->{
            for (int i = 1; i <=10 ; i++) {
                try {
                    shareData.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"consumer01").start();
}

这里用了lambda表达式,不会的可看我之前的文章

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\idea\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar=65095:D:\idea\IntelliJ IDEA 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\李肇京\IdeaProjects\JUC\out\production\JUC" JUC_01_SellTicket.ThreadWaitNotifyDemo
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
producer01	当前个数1
consumer01	当前个数0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值