我有这个测试代码:
ExecutorService pool = Executors.newFixedThreadPool(1);
System.out.println("Starting adding new messages to pool");
for (int i = 0; i < 60; i++) {
pool.submit(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("Done!");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
System.out.println("End of the program");
Thread.sleep(10_000);
如果我运行它,我会看到:
Starting adding new messages to pool
End of the program
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
但是当缓冲区已满时,我需要让线程池生产者阻塞,然后在控制台中我会得到:
Starting adding new messages to pool
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
Done!
我怎样才能做到这一点?
添加:
如果要在池已满时阻止 for 循环,则应使用信号量:
借助Java,无需自行编写自行车
UPD不是没有自写的自行车,而是自行车的尺寸比有信号量的小。
借助参数
maxItemsInTheQueue,您可以控制队列中可以等待的元素数量。如果为 0,我们使用SynchronousQueue(任务不进入队列,生产者正在等待空闲线程),如果更多 - 然后ArrayBlockingQueue(任务进入队列直到队列满,然后生产者开始等待空闲线程)。此外,您可以
offer(r, Long.MAX_VALUE, TimeUnit.NANOSECONDS)对其进行配置,以便等待队列中的空闲槽不会是无限的,而是会超时。