【发布时间】:2020-04-07 20:16:09
【问题描述】:
我正在制作一个包含两个线程的应用程序:其中一个将值写入 LinkedBlockingQueue,另一个正在读取。我正在使用 ScheduledExecutorService 在几秒钟内运行此操作。 问题是我的应用程序冻结了 BlockingQueue 的方法,我不明白为什么。
这是一个常见的资源:
class Res{
AtomicInteger atomicInteger = new AtomicInteger(0);
BlockingQueue<String> q = new LinkedBlockingQueue<>();
}
这是读者
Semaphore semaphore = new Semaphore(1); /this is for reader does not take two places in thread pool
Runnable reader = ()->{
try {
semaphore.acquire();
System.out.println(res.q.take()+" "+res.atomicInteger.incrementAndGet());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
作者:
Runnable writer = ()->{
res.q.add("hi");
};
完整代码:
class Res{
AtomicInteger atomicInteger = new AtomicInteger(0);
BlockingQueue<String> q = new LinkedBlockingQueue<>();
}
public class Main {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
Res res = new Res();
Semaphore semaphore = new Semaphore(1); //this is for reader does not take two places in thread pool
Runnable reader = ()->{
try {
semaphore.acquire();
System.out.println(res.q.take()+" "+res.atomicInteger.incrementAndGet());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable writer = ()->{
res.q.add("hi");
};
Random rnd = new Random();
for (int i = 0; i < 20; i++) {
int time = rnd.nextInt(5)+ 2;
executorService.schedule(writer,time, TimeUnit.SECONDS);
}
for (int i = 0; i < 20; i++) {
int time = rnd.nextInt(5)+ 2;
executorService.schedule(reader,time, TimeUnit.SECONDS);
}
executorService.shutdown();
}
它应该打印二十行“hi [number]”,但在某些行上冻结。 比如我现在的打印:
hi 1
hi 2
hi 3
hi 4
hi 5
我发现如果我增加线程数newScheduledThreadPool(20) 它会开始工作,但是我怎样才能用两个线程来实现呢?谢谢!
【问题讨论】:
-
您的执行程序从两个线程开始。当这两个线程在调用您的
reader对象时被阻塞并且队列为空时,您认为会发生什么?
标签: java java-8 concurrency blockingqueue linkedblockingqueue