java多线程中的等待唤醒机制--多生产者多消费者问题

news/2024/7/7 7:04:05

在java多线程中,等待唤醒机制是最经典的也是最能够体现java多线程中的线程安全的问题,在写等待唤醒机制的时候,我们要先去了解什么是等待唤醒机制

等待唤醒机制就是指在多个线程进行并发的去操作同一个资源的问题,
以生产馒头和消费馒头举例;就比如我们有一个容器(resource,代表的是馒头的存放),这里面设置的是两个变量,i(表示的是馒头的数量)和name(表示的是馒头这个名字),线程0和线程1是生产馒头的线程,线程2和线程3是消费馒头的线程。在线程0或线程1进行生产馒头之后,线程2或者线程3就接着去消费这个馒头
这里写图片描述
由上图可知,在生产者消费者中,我们要去定义一个公共的资源,Resource,这四个线程都去共享这个资源。
代码如下

package java多线程;

/*
 * java的等待/唤醒机制
 * 生产者/消费者的问题:多生产者多消费者的问题
 */

//定义的是资源
class AResource {
    private String name;
    private int count = 1;
    private boolean flag = false;

    public synchronized void set1(String name) {
        while (flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        this.name = name;
        count++;
        flag = true;
        notifyAll();
        System.out.println(Thread.currentThread().getName() + "....生产者..." + this.name + this.count);

    }

    public synchronized void eat() {
        // while是解决每一次启动线程都要去判断标记的方式
        while (!flag) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        System.out.println(Thread.currentThread().getName() + "....消费者..." + this.count);
        flag = false;
        notifyAll();
        // 这个方法是为了方式线程死锁的问题
    }
}

// 定义生产者
class Producer implements Runnable {
    private AResource ar;

    public Producer(AResource ar) {
        this.ar = ar;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            ar.set1("馒头");
        }
    }

}

// 定义消费者
class Consumer implements Runnable {
    private AResource ar;

    public Consumer(AResource ar) {
        // TODO Auto-generated constructor stub
        this.ar = ar;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            ar.eat();
        }
    }

}

public class ProducerConsumerExample {
    public static void main(String[] args) {
        AResource ar = new AResource();
        // 这个表示的是生产者的任务
        Producer pr = new Producer(ar);
        // 这个表示的是消费者的任务
        Consumer con = new Consumer(ar);
        new Thread(pr).start();
        new Thread(pr).start();// 两个生产者的线程,其实是一个生产者的任务

        new Thread(con).start();
        new Thread(con).start();// 两个消费者的线程,其实是一个消费者的任务
    }
}

总结:好好的复习自己基础是很重要的啊,基础就是技术的基石!!!


http://www.niftyadmin.cn/n/3091677.html

相关文章

python作业代做_代做MATH 6141作业、代写Python课程设计作业、代做algorithms作业、代做Python编程作业...

代做MATH 6141作业、代写Python课程设计作业、代做algorithms作业、代做Python编程作业 日期:2018-12-05 11:11 Coursework 2: MATH 3018/MATH 6141 - Numerical methods Due: 13 December 2018 In this coursework you will implement given numerical algorithms.…

偏门套路:每天被动吸引150+精准淘宝粉

网上关于引流技巧的文章五花八门,看得你热血澎湃,但往往搞一两天大多数人就放弃了,甚至看完后根本没去操作。最后还抱怨:为什么我看了那么多东西还是赚不到钱!虽然我十分鄙视这种浮躁的心态,但也能够理解和体谅大家。因…

使用hibernate中的hql进行分页设置setMaxResults(int a)出错

今天在自己写项目的时候在进行hibernate分页的时候设置setMaxResults(int a)的时候一直出现错误 org.hibernate.exception.SQLGrammarException: could not execute queryat org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)at org.hibernate.e…

python数据分类_在python中将数据分类为具有相同间隔大小的n类别

假设我想将以下数据分类为12类: no. grades 0 9.08 1 8.31 2 7.42 3 7.42 4 7.42 5 7.46 6 9.67 7 11.77 8 8.81 9 6.44 10 9.40 11 9.06 12 10.52 13 6.19 14 5.04 15 5.04 16 9.44 17 5.87 18 2.67 19 6.99 20 9.08 21 6.64 22 4.83 23 4.47 24 6.61 25 6.61 26 7…

前后台JSON传值得一个问题和异常处理net.sf.json.JSONException: Unquotted string 'name'...

项目中做导入的时候遇到个bug,用JSON.stringify()序列号json对象传给后台;然后后台通过getPatameter()获取值时,前台的英文引号变成了中文引号。 原来代码如下:(自己排查发现就算是英文的时候也是如此) //提…

控制反转(ioc)和依赖注入 【很详细】

文章目录前言什么是控制反转什么是依赖注入总结前言 最近在学习Spring框架,它的核心就是IoC容器。要掌握Spring框架,就必须要理解控制反转的思想以及依赖注入的实现方式。下面,我们将围绕下面几个问题来探讨控制反转与依赖注入的关系以及在S…

java并发-线程池的介绍

http://www.infoq.com/cn/articles/java-threadPool?utm_sourceinfoq&utm_campaignuser_page&utm_mediumlink 本文转自 古道卿 51CTO博客,原文链接:http://blog.51cto.com/gudaoqing/1927574

python 根据地址求经纬度 谷歌_python爬虫获取小区经纬度以及结构化地址

本文实例为大家分享了python爬虫获取小区经纬度、地址的具体代码,供大家参考,具体内容如下 通过小区名称利用百度api可以获取小区的地址以及经纬度,但是由于api返回的值中的地址形式不同,所以可以首先利用小区名称进行一轮爬虫&am…