我试图在java中使用semaphores
来实现Producer和Consumer问题。问题是,当我启动两个线程(生产者和消费者)时,消费者在缓冲区已满后无法启动和生成器块。我的意思是看起来只有一个线程以同步方式工作。因此,正如我所提到的,我使用3个信号量,它们是空的,完整的和互斥的。这是最简单的代码;
制作人类;
import java.util.concurrent.Semaphore;
public class Producer implements Runnable {
private Semaphore empty;
private Semaphore full;
private Semaphore mutex;
public Producer(Semaphore empty, Semaphore full, Semaphore mutex) {
this.empty = empty;
this.full = full;
this.mutex = mutex;
}
@Override
public void run() {
while (true) {
try {
empty.acquire();
mutex.acquire();
Thread.sleep(500);
System.out.println("Producer producess an element");
mutex.release();
full.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者类;
import java.util.concurrent.Semaphore;
public class Consumer implements Runnable {
private Semaphore empty;
private Semaphore full;
private Semaphore mutex;
public Consumer(Semaphore empty, Semaphore full, Semaphore mutex) {
this.empty = empty;
this.full = full;
this.mutex = mutex;
}
@Override
public void run() {
while (true) {
try {
full.acquire();
mutex.acquire();
Thread.sleep(500);
System.out.println("Consumer consumes an element");
mutex.release();
empty.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ProducerConsumerExample类
import java.util.concurrent.Semaphore;
public class ProducerConsumerProblem {
private Semaphore empty;
private Semaphore full;
private Semaphore mutex;
public ProducerConsumerProblem(int empty, int full) {
this.empty = new Semaphore(empty);
this.full = new Semaphore(full);
this.mutex = new Semaphore(1);
}
public void runProducerConsumerExample() {
Producer producer = new Producer(empty, full, mutex);
Consumer consumer = new Consumer(empty, full, mutex);
Thread p = new Thread(producer);
Thread c = new Thread(consumer);
p.run();
c.run();
}
}
最后测试课程
import org.junit.Before;
import org.junit.Test;
public class ProducerConsumerProblemTest {
private ProducerConsumerProblem testClass;
private static final int EMPTY = 10;
private static final int FULL = 0;
@Before
public void setUp() {
testClass = new ProducerConsumerProblem(EMPTY, FULL);
}
@Test
public void testName() {
testClass.runProducerConsumerExample();
}
}
输出:
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
生成10个项目后,没有任何事情发生,线程被阻止。
答案 0 :(得分:2)
请勿使用run()
,请使用start()
p.run();
c.run();
应该是
p.start();
c.start();
调用run()
不会生成新的执行线程。它只运行当前执行线程中的功能。
有关详细信息,请参阅this question/answer。
另请注意,我会在测试运行结束时正确关闭线程(否则,在添加/运行测试时,您将构建多个线程)。中断你的线程或设置一个volatile布尔值,表明你的循环应该完成。