gpt4 book ai didi

java - 偶数、奇数和偶数消费者-生产者

转载 作者:行者123 更新时间:2023-12-01 11:03:33 30 4
gpt4 key购买 nike

我在这里想做的是由偶数消费者打印偶数,由奇数消费者打印奇数。

有一个 evenodd 方法,它基本上消耗任何数字并打印(无论是偶数还是奇数)。我有 2 个偶数消费者线程、2 个奇数消费者线程、2 个偶数消费者线程和 3 个生产者线程。

我对信号量概念很陌生,我尝试使用它。当我删除 evenodd 方法和相关线程时,我得到了正确的输出,即偶数线程的偶数和奇数线程的奇数。但是当我再次放置 evenodd 方法和 evenodd 线程时,我遇到了死锁。

如果有人能指导我,我哪里出了问题以及如何解决它,那将非常有帮助。请详细说明如何实现 evenodd 方法,以便它能够正常工作。

package lab61;

import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class Process {

Semaphore empty;
Semaphore full;
Semaphore even;
Semaphore odd;
Semaphore mutex;
//Semaphore evenodd;
boolean evenb;
boolean oddb,eo;

LinkedList<Integer> list;
Random random;


public Process(int capacity){
list=new LinkedList<Integer>();

empty=new Semaphore(capacity);

full=new Semaphore(0,true);
mutex=new Semaphore(1,true);

even=new Semaphore(0,true);
evenb=false;
oddb=false;
eo=false;

odd=new Semaphore(0,true);
//evenodd = new Semaphore(0,true);

random=new Random();
}

public void Producer() throws InterruptedException{

while(true){

int a=random.nextInt(100);

empty.acquire();
mutex.acquire();

list.add(a);
System.out.println("Producing "+a);
System.out.println(list);



if((list.get(0)%2)==0){
if(!evenb){
even.release();
evenb = true;
}
}else if((list.get(0)%2)==1){
if(!oddb){
odd.release();
oddb = true;
}


}
/*if(((list.get(0)%2)==0)||((list.get(0)%2)==1)){
if(!eo){
evenodd.release();
eo = true;
}
}*/


mutex.release();


full.release();


}

}

public void consumereven() throws InterruptedException{
while(true){
//Thread.sleep(2000);
even.acquire();
Thread.sleep(2000);
full.acquire();

mutex.acquire();

int value = list.removeFirst();
System.out.println("I am the even consumer "+ value);
evenb = false;
System.out.println(list);

mutex.release();
empty.release();

}

}


public void consumerodd() throws InterruptedException{
while(true){

//Thread.sleep(2000);
odd.acquire();
Thread.sleep(2000);
full.acquire();
//odd.acquire();
mutex.acquire();
int value = list.removeFirst();
System.out.println("I am the odd consumer "+ value);
System.out.println(list);
oddb = false;
mutex.release();
empty.release();

}

}
public void evenodd() throws InterruptedException {
while(true){

full.acquire();
mutex.acquire();
int value = list.removeFirst();
System.out.println("i am the evenodd consumer " + value );

if((list.get(0)%2)==0){
if(oddb=true){
odd.acquire();
oddb=false;
}
if(evenb==false){
even.release();
evenb = true;
}
}
else if((list.get(0)%2)==1){
if(evenb=true){
even.acquire();
evenb=false;
}
if(oddb==false){
odd.release();
oddb = true;
}
}
System.out.println(list);


mutex.release();
empty.release();
}
}



}
package lab61;

import lab6.producer;

public class App {


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

Process p=new Process(10);


Thread producer1=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.Producer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
});


Thread producer2=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.Producer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
});

Thread producer3=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.Producer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
});



Thread consumereven1=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumereven();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}
});

Thread consumereven2=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumereven();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}
});

Thread consumerodd1=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumerodd();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}
});
Thread consumerodd2=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumerodd();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}
});
Thread evenodd1=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.evenodd();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}
});
Thread evenodd2=new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
try {
p.evenodd();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



}
});


producer1.start();
producer2.start();
producer3.start();
consumereven1.start();
consumereven2.start();
consumerodd1.start();
consumerodd2.start();
evenodd1.start();
evenodd2.start();

producer1.join();
producer2.join();
producer3.join();
consumereven1.join();
consumereven2.join();
consumerodd1.join();
consumerodd2.join();
evenodd1.join();
evenodd2.join();

}





}

最佳答案

该代码可能会导致死锁,因为 consumereven()consumerodd() 方法获取 evenodd > 信号量位于 fullmutex 信号量之前,而 evenodd() 方法获取 full偶数奇数信号量之前互斥信号量。这会导致这样一种情况:运行 consumereven() 的线程具有 even 信号量,但在等待 full 信号量时被阻塞,而运行evenodd()的线程拥有full信号量,但在even信号量上被阻塞,因此两个线程陷入死锁。

为了帮助防止死锁,当您使用多个锁时,最好始终以相同的顺序获取它们,无论它们在哪里使用,并以与获取相反的顺序释放它们。

关于java - 偶数、奇数和偶数消费者-生产者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33151192/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com