我使用信号量进行线程通信我有两个线程,一个是OddThread,另一个是EvenThread,我打印值从1到10 OddThread将只打印1到10之间的奇数,而EvenThread线程只打印1之间的偶数因为我已经使用信号量来让线程正常通信。实际上发生的事情是OddThread只打印1而EvenThread只打印2然后两者都停止了。我并不知道实际发生的事情。任何人都建议。
public class ThreadProducerConsumerSemaphore {
/**
* @param args
*/
public static void main(String[] args) {
Semaphore p = new Semaphore(1);
Semaphore c = new Semaphore(0);
OddThread producer = new OddThread(p, c);
EvenThread consumer = new EvenThread(p, c);
Thread t1 = new Thread(producer, "Thread producer");
Thread t2 = new Thread(consumer, "Thread consumer");
t1.start();
t2.start();
}
}
class OddThread implements Runnable {
Semaphore p;
Semaphore c;
public OddThread(Semaphore p, Semaphore c) {
super();
this.p = p;
this.c = c;
}
int counter = 1;
@Override
public void run() {
while (true) {
try {
p.acquire(1);
System.out.println(Thread.currentThread().getName() + " "
+ counter);
if (counter == 10) {
break;
}
counter++;
c.release(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class EvenThread implements Runnable {
Semaphore p;
Semaphore c;
int counter = 2;
public EvenThread(Semaphore p, Semaphore c) {
super();
this.p = p;
this.c = c;
}
@Override
public void run() {
while (true) {
try {
c.acquire(1);
System.out.println(Thread.currentThread().getName() + " "
+ counter);
if (counter == 10) {
break;
}
counter=counter+2;
p.acquire(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
答案 0 :(得分:0)
你的代码不正确,甚至不对称。
p.acquire(1);
c.release(1);
c.acquire(1);
p.acquire(1);
答案 1 :(得分:0)
您的EvenThread.run
方法同时获取c
和p
,而不是释放其中一个。
但请注意,即使修复了代码,您的代码看起来也不会正常退出。考虑一下:两个线程在退出之前都不会释放信号量,因此其中一个线程将不可避免地被阻塞。
答案 2 :(得分:0)
这是你的问题:
............
c.acquire(1);
System.out.println(Thread.currentThread().getName() + " "
+ counter);
if (counter == 10) {
break;
}
counter=counter+2;
p.acquire(1); <--deadlock this has already been acquired by the other thread.
..............
你应该在这里释放p,以允许另一个线程继续;所以用p.release(1)
替换我指示的行,它应该没问题。