以下のリンクで述べたように: -
キューに入れる前に ThreadPoolExecutor でスレッドを最大まで増やすにはどうすればよいですか?
要素に入った後に false を返すようにキューの実装を変更しました。その結果、新しいタスクがキューに挿入されるたびに、新しいスレッドが作成されます。
しかし、ロガーを配置して大規模な (Bi システム テスト) 以下の実装を実行すると、新しい問題が生成されます。
タスクが実行されると、そのタスクはキューに挿入され、キューが false を返すと、その実行のために新しいスレッドが作成されます。現在プールにあるアイドル スレッドは取得されません。getTask()
理由は、タスクがキューからタスクを選択するメソッドからアイドル状態のスレッドに割り当てられるためです。したがって、私の質問は、スレッドがアイドル状態の場合、新しいスレッドを作成するのではなく、アイドル状態のスレッドに実行用のタスクが割り当てられるように、この動作を変更する方法です??
以下の出力により、より明確になります。
Task 46 ends
Active Count: 0 Pool Size : 3 Idle Count: 3 Queue Size: 0
Task 47 ends
Active Count: 0 Pool Size : 3 Idle Count: 3 Queue Size: 0
Task 48 ends
Active Count: 0 Pool Size : 3 Idle Count: 3 Queue Size: 0
Active Count: 1 Pool Size : 4 Idle Count: 3 Queue Size: 0
Task 49 ends
Active Count: 2 Pool Size : 5 Idle Count: 3 Queue Size: 0
Task 50 ends
Active Count: 2 Pool Size : 5 Idle Count: 3 Queue Size: 0
コード ファイルは次のとおりです。
サーバー マシンで 1.5 を使用しており、アップグレードできないため、ThreadPoolExecutor のバージョンは Java 1.5 です。
ThreadPoolExecutor:-
public void execute(Runnable command) {
System.out.println("Active Count: " + getActiveCount()
+ " Pool Size : " + getPoolSize() + " Idle Count: "
+ (getPoolSize() - getActiveCount())+" Queue Size: "+getQueue().size());
if (command == null)
throw new NullPointerException();
for (;;) {
if (runState != RUNNING) {
reject(command);
return;
}
if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
return;
if (workQueue.offer(command))
return;
int status = addIfUnderMaximumPoolSize(command);
if (status > 0) // created new thread
return;
if (status == 0) { // failed to create thread
reject(command);
return;
}
// Retry if created a new thread but it is busy with another task
}
}
LinkedBlockingQueue:-
public class CustomBlockingQueue<E> extends LinkedBlockingQueue<E>
{
/**
*
*/
private static final long serialVersionUID = 1L;
public CustomBlockingQueue() {
super(Integer.MAX_VALUE);
}
public boolean offer(E e) {
return false;
}
}
拒否ハンドラでは、オーバーライドしていないキューの put メソッドを呼び出しています
Callingexecutor
final CustomThreadPoolExecutor tpe = new CustomThreadPoolExecutor(3, 8, 0L, TimeUnit.MILLISECONDS, new MediationBlockingQueue<Runnable>(), new MediationRejectionHandler());
private static final int TASK_COUNT = 100;
for (int i = 0; i < TASK_COUNT; i++) {
......
tpe.execute(new Task(i));
.....
}
コア プール サイズを 3、最大プール サイズを 8 としてエグゼキュータを呼び出し、タスクに無制限のリンク ブロッキング キューを使用しています。