java生产消费者代码 java生产消费者代码是多少

java多生产者和多消费者

public static void main(String[] args) {

专注于为中小企业提供成都网站建设、成都网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业芒市免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了千余家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

Buffer buffer=new Buffer(); //创建一个临界区对象

new Producer(buffer,100).start(); //创建一个生产者对象,并启动其线程

new Consumer(buffer,200).start(); //创建一个消费者对象,并启动其线程

new Consumer(buffer,201).start(); //创建第二个消费者对象,并启动其线程

}

这一段代码,多加入

new Consumer(buffer,201).start(); //创建第二个消费者对象,并启动其线程

多加一段代码创建一个消费者

多加入

new Producer(buffer,100).start();

创建一个生产者。

想要很多生产者和消费者?加就是了啊。

第四个文件 Buffer.java

这个是实现同步的主要缓存类。想要实现同步

在每个方法的声明前都加入synchronized 就行

synchronized 线程锁,很好用的。源代码已经加入了

就比如

public synchronized void put(int value) { //同步方法控制临界区内容写入

java多生产者和消费者问题,重复生产消费

我晕看了好久,别人写的代码看的真是辛苦,也没注释...修改了一堆括号!!

妥妥的没问题,你的资源用的数组,换句话说,

你数组被A1线程增加索引1,然后B过来拿走索引1; 数组里面此刻是什么?当然是0了啊;因为你递减了...

然后A2被拿到执行权,怎么样?是不是还去增加索引1??明白了?

如果你想要不重复,就别递减就行了!

另外你这么改,有什么问题看的很醒目,知道发生在哪个线程上!

JAVA怎么编多个生产者多个消费者代码啊

public class ProduceConsumerDemo {

public static void main(String[] args) {

// 1.创建资源

Resource resource = new Resource();

// 2.创建两个任务

Producer producer = new Producer(resource);

Consumer consumer = new Consumer(resource);

// 3.创建线程

/*

* 多生产多消费产生的问题:重复生产、重复消费

*/

Thread thread0 = new Thread(producer);

Thread thread1 = new Thread(producer);

thread0.setName("生产者(NO0)");

thread1.setName("生产者(NO1)");

Thread thread2 = new Thread(consumer);

Thread thread3 = new Thread(consumer);

thread2.setName("消费者(NO2)");

thread3.setName("消费者(NO3)");

thread0.start();

thread1.start();

thread2.start();

thread3.start();

}

}

class Resource {

private String name;

private int count = 1;

// 定义标记

private boolean flag;

// 提供给商品赋值的方法

public synchronized void setName(String name) {// thread0, thread1在这里运行

while (flag)// 判断标记为true,执行wait等待,为false则生产

/*

* 这里使用while,而不使用if的理由如下:

* thread0有可能第二次也抢到锁的执行权,判断为真,则有面包不生产,所以接下来执行等待,此时thread0在线程池中。

* 接下来活的线程有3个(除了thread0),这三个线程都有可能获取到执行权.

* 假设thread1获得了执行权,判断为真,则有面包不生产,执行等待。此时thread1又进入到了线程池中。

* 接下来有两个活的线程thread2和thread3。 假设thread2又抢到了执行权,所以程序转到了消费get处……

*/

try {

this.wait();//这里wait语句必须包含在try/catch块中,抛出异常。

} catch (InterruptedException e) {

e.printStackTrace();

}

this.name = name + count;// 第一个面包

count++;// 2

System.out.println(Thread.currentThread().getName() + this.name);// thread0线程生产了面包1

// 生产完毕,将标记改成true.

flag = true;// thread0第一次生产完面包以后,将标记改为真,表示有面包了

// 唤醒消费者(这里使用notifyAll而不使用notify的原因在下面)

this.notifyAll();// 第一次在这里是空唤醒,没有意义

}

/*

* 通过同步,解决了没生产就消费的问题

* 生产完以后,生产者释放了this锁,此时,生产者和消费者同时去抢锁,又是生产者抢到了锁,所以就出现了一直生产的情况。

* 与“生产一个就消费一个的需求不符合” 等待唤醒机制 wait();该方法可以使线程处于冻结状态,并将线程临时存储到线程池

* notify();唤醒指定线程池中的任意一个线程。 notifyAll();唤醒指定线程池中的所有线程

* 这些方法必须使用在同步函数中,因为他们用来操作同步锁上的线程上的状态的。

* 在使用这些方法时候,必须标识他们所属于的锁,标识方式就是锁对象.wait(); 锁对象.notify(); 锁对象.notifyAll();

* 相同锁的notify()可以获取相同锁的wait();

*/

public synchronized void getName() {// thread2,thread3在这里运行

while (!flag)

/*

* ……接着上面的程序执行分析 thread2拿到锁获取执行权之后,判断!flag为假,则不等待,直接消费面包1,输出一次.

* 消费完成之后将flag改为假 接下来又唤醒了thread0或者thread1生产者中的一个

* 假设又唤醒了thread0线程,现在活的线程有thread0,thread2,thread3三个线程

* 假设接下来thread2又抢到了执行权,判断!flag为真,没面包了,停止消费,所以thread2执行等待.

* 此时活着的线程有thread0和thread3。

* 假设thread3得到了执行权,拿到锁之后进来执行等待,此时活着的线程只有thread0.

* 所以thread0只能抢到执行权之后,生产面包2,将标记改为true告诉消费者有面包可以消费了。

* 接下来执行notify唤醒,此时唤醒休眠中的3个线程中的任何一个都有可能。

* 如果唤醒了消费者thread2或者thread3中的任何一个,程序都是正常。如果此时唤醒thread1则不正常。

* 如果唤醒了thread1,此时活着的线程有thread0和thread1两个线程。

* 假设thread0又获得了执行权,判读为真有面包,则又一次执行等待。

* 接下来只有thread1线程有执行权(此时没有判断标记直接生产了,出错了),所以又生产了面包3。 在这个过程中,面包2没有被消费。

* 这就是连续生产和消费容易出现的问题。

* 原因:被唤醒的线程没有判断标记就开始执行了,导致了重复的生产和消费发生。

* 解决:被唤醒的线程必须判断标记,使用while循环标记,而不使用if判断的理由。

* 但是接下来会出现死锁,原因在于:

* 上面的程序中thread0在执行notify的时候唤醒了thread1,而此时thread2和thread3两个消费者线程都处于等待状态

* thread1在执行while判断语句之后判断为真,则执行等待,此时所有的线程都处于冻结等待状态了。

* 原因:本方线程在执行唤醒的时候又一次唤醒了本方线程,而本方线程循环判断标记又继续等待,而导致所有的线程都等待。

* 解决:本方线程唤醒对方线程, 可以使用notifyAll()方法

*  唤醒之后,既有本方,又有对方,但是本方线程判断标记之后,会继续等待,这样就有对方线程在执行。

*/

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()  + this.name);

// 将标记改为false

flag = false;

// 唤醒生产者

this.notify();

}

}

// 生产者

class Producer implements Runnable {

private Resource resource;

public Producer(Resource resource) {

this.resource = resource;

}

public void run() {

while (true) {

resource.setName("面包");

}

}

}

// 消费者

class Consumer implements Runnable {

private Resource resource;

public Consumer(Resource resource) {

this.resource = resource;

}

@Override

public void run() {

while (true) {

resource.getName();

}

}

}

Java 生产者,消费者代码中,如果使用if和notify()函数,其中生产者两个线程,消费者一

线程的运行时随机的,它不是交替运行的,如果只有这两个线程的话,每次运行都会进行一个二选一的选择.

你参考一下

public class ThreadABC extends Thread{

int i=0;

private static int count=0;

private static Object o=new Object();

public ThreadABC(String ID){

currentThread().setName(ID);

}

public void run() {

synchronized (o) {

while(true){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if(count%2==0currentThread().getName().equals("A")){

o.notify();

System.out.print(currentThread().getName());

count++;

try {

o.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

else if (count%2==1currentThread().getName().equals("B")) {

o.notify();

System.out.print(currentThread().getName());

count++;

try {

o.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}

public static void main(String[] args) {

ThreadABC b=new ThreadABC("B");

ThreadABC a=new ThreadABC("A");

a.setName("A");

b.setName("B");

a.start();

b.start();

}

}

网站栏目:java生产消费者代码 java生产消费者代码是多少
分享链接:https://www.cdcxhl.com/article46/dodoehg.html

成都网站建设公司_创新互联,为您提供外贸建站建站公司营销型网站建设全网营销推广关键词优化外贸网站建设

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

外贸网站制作