我正在学习java,我正在实现一个基本的生产者 - 消费者用例。 我有一个队列和一些生产者将东西插入这个队列。 我还有一个实现Callable的Consumer。以下是Consumer的实现:
public String call() throws Exception
{
while(true) {
if(!queue.isEmpty()) {
String prod = queue.poll();
System.out.println(name + " consumed " + prod);
}
}
}
制片:
@Override
public void run() {
System.out.println("adding " + name);
queue.add(name);
}
主:
public static void main(String[] args) {
Test();
}
public static void Test()
{
Queue<String> queue = new LinkedList<String>();
ScheduledExecutorService lots_of_producers = Executors.newScheduledThreadPool(10);
ExecutorService consumers = Executors.newFixedThreadPool(1);
for(int i=0; i<1; i++) {
Consumer consumer = new Consumer("consumer_" + i, queue);
consumers.submit(consumer);
}
for(int i=0; i<5; i++) {
Producer producer = new Producer("producer_" + i, queue);
lots_of_producers.scheduleWithFixedDelay(producer, i, 5, TimeUnit.SECONDS);
}
}
生产者工作正常,但消费者无法工作,因为我没有看到消费者的日志。
但是,如果我在queue.isEmpty()为true时更改了使用实现并让使用者线程休眠,则使用者可以按预期工作。
public String call() throws Exception
{
while(true) {
if(!queue.isEmpty()) {
String prod = queue.poll();
System.out.println(name + " consumed " + prod);
} else {
Thread.sleep(100);
}
}
}
有人可以解释为什么消费者线程在第一种情况下不起作用吗?
同样对于第一种情况,在eclipse中我可以看到消费者线程没有死。我暂停它,它正在这条线上工作
if(!queue.isEmpty()) {
现在,如果我手动切换,消费者将工作并打印日志。但是一旦我恢复并让它自行运行,它就会再次卡住。
我试图更多地了解java。
谢谢!
-Erben
答案 0 :(得分:4)
在这种情况下存在多个问题。
Thread.sleep
)为其他线程提供了运行的机会。这就是为什么你看到消费者消费的原因,因为生产者线程有机会将数据放入队列中。但是,即使是这个也是失败的,因为你没有同步生产者和消费者。有关学习线程同步的信息,请参阅Java Tutorial - Synchronization。