我想在这里做的是甚至消费者打印偶数,奇数消费者打出奇数。
有evenodd
方法基本上消耗任何数字和打印(无论是偶数还是奇数)。我有2个even
个消费者线程,2个odd
个消费者线程,2个evenodd
个消费者线程和3个producer
个线程。
我是信号量概念的新手,我尝试过使用它。当我删除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();
}
}
答案 0 :(得分:1)
代码可能导致死锁,因为consumereven()
和consumerodd()
方法在even
和odd
信号量之前获取full
或mutex
信号量,evenodd()
方法在full
或mutex
信号量之前获取even
和odd
信号量。这导致一种情况,例如,运行consumereven()
的线程具有even
信号量但在等待full
信号量时被阻塞,而运行evenodd()的线程具有{full
信号量。 1}}信号量,但在even
信号量上被阻塞,因此两个线程都已死锁。
为了帮助防止死锁,当您使用多个锁时,最好始终以相同的顺序获取它们,并以相反的顺序释放它们。
答案 1 :(得分:0)
这不是一个好方法,但你可以做类似的事情。
import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;
public class P1 {
Semaphore empty;
Semaphore full;
Semaphore even;
Semaphore odd;
Semaphore mutex;
Semaphore oddeven;
LinkedList<Integer> list;
Random random;
boolean oddb;
boolean evenb;
boolean oddevenb;
public P1(int capacity){
list=new LinkedList<Integer>();
empty=new Semaphore(capacity,true);
full=new Semaphore(0,true);
mutex=new Semaphore(1,true);
even=new Semaphore(0,true);
odd=new Semaphore(0,true);
oddeven=new Semaphore(0,true);
oddb=false;
evenb=false;
oddevenb = false;
random=new Random();
}
public void Producer(String s) throws InterruptedException{
while(true){
int a=random.nextInt(100);
empty.acquire();
mutex.acquire();
list.add(a);
System.out.println("Producing "+a+" By "+s);
System.out.println(list);
int temp=random.nextInt(3)+1;
if(temp==1 ){
if(oddevenb==false){
oddeven.release();
oddevenb=true;
evenb=true;
oddb=true;
}
}
else{
if((list.get(0))%2==0){
if(evenb==false){
even.release();
evenb=true;
oddevenb=true;
}
}else if((list.get(0))%2==1){
if( oddb==false) {
odd.release();
oddevenb=true;
oddb=true;
}
}
}
mutex.release();
full.release();
}
}
public void consumereven(String s) throws InterruptedException{
while(true){
// Thread.sleep(5000);
even.acquire();
full.acquire();
mutex.acquire();
int value=list.removeFirst();
System.out.println("I am the "+ s +" consumer "+value);
evenb=false;
oddevenb=false;
System.out.println(list);
mutex.release();
empty.release();
}
}
public void consumerodd(String s) throws InterruptedException{
while(true){
//Thread.sleep(5000);
odd.acquire();
full.acquire();
mutex.acquire();
int value= list.removeFirst();;
System.out.println("I am the "+s+" consumer "+value);
oddb=false;
oddevenb=false;
System.out.println(list);
mutex.release();
empty.release();
}
}
public void consumeroddeven(String s) throws InterruptedException{
while(true){
//Thread.sleep(5000);
oddeven.acquire();
full.acquire();
mutex.acquire();
int value= list.removeFirst();;
System.out.println("I am the "+s+" "+value);
System.out.println(list);
oddevenb=false;
evenb=false;
oddb=false;
mutex.release();
empty.release();
}
}
}
public class App3 {
public static void main(String[] args) throws InterruptedException{
final P1 p=new P1(10);
Thread producer=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.Producer("p1");
} 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("p2");
} 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("p3");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"p3");
Thread consumereven=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumereven("even1");
} 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("even2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread consumerodd=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumerodd("odd1");
} 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("odd2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread consumer=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumeroddeven("NC1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread consumer1=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
p.consumeroddeven("NC2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
producer.start();
producer2.start();
producer3.start();
consumereven.start();
consumereven2.start();
consumerodd.start();
consumerodd2.start();
consumer.start();
consumer1.start();
producer.join();
producer2.join();
producer3.join();
consumereven.join();
consumereven.join();
consumereven2.join();
consumerodd.join();
consumerodd.join();
consumerodd2.join();
consumer.join();
consumer1.join();
}
}