boundedExecutorを作成したいが、固定数のスレッドのみを並列実行できる。より多くのタスクが追加されると、エグゼキュータは他のスレッドが完了するまでブロックします。executorService throw SynchronousQueueを使用したRejectException
ここに私は他の質問で見つけた実行者です。
public class BoundedExecutor extends ThreadPoolExecutor {
private final Logger logger = LogManager.getLogger(BoundedExecutor.class);
private final Semaphore semaphore;
public BoundedExecutor(int bound){
super(bound, bound, 0, TimeUnit.SECONDS, new SynchronousQueue<>());
this.semaphore = new Semaphore(bound);
}
@Override
public void execute(Runnable task) {
try {
semaphore.acquire();
super.execute(task);
} catch (InterruptedException e) {
logger.error("interruptedException while acquiring semaphore");
}
}
protected void afterExecute(final Runnable task, final Throwable t){
super.afterExecute(task, t);
semaphore.release();
}
}
と私はコードがシングルスレッドを作り、順次タスクを実行しますが、実際には、ときに最初のタスクの完全な、エグゼキュータはjava.util.concurrent.RejectedExecutionExceptionスロー思っ
public static void main(String[] args) throws Exception {
Runnable task =() -> {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " complete.");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
BoundedExecutor pool = new BoundedExecutor(1);
for(int i = 0; i < 10; i++){
pool.execute(task);
}
pool.shutdown();
}
メインコード。
私が理解したように、semaphore.acquire()は最初のタスクが完了してセマフォをリリースするまでスレッドをブロックしますが、コードに何が問題なのですか?
なぜあなたはSynchronousQueueでセマフォを使用しているセマフォを使用してキューのブロックを作っていないでしょうか?これで何を達成しようとしていますか? –
セマフォは、プールが一杯になったときにThreadExecutor add newタスクをブロックするために使用されます。 プールが一杯になったときにタスクをキューに入れたくないので、synchronousQueueが使用されます。 – iceshi
SynchronousQueueを使用すると、フリースレッドがないときはいつでもブロックされます。セマフォはこれに何を追加しますか? –