Javaスレッドプールタスクの実行後にスレッドを回収
20477 ワード
Javaスレッドプールタスクの実行後にスレッドを回収
スレッドプール内のすべてのタスクが実行されると、スレッドは停止せず、JVMにOOMの問題が発生します.その後、次のリンクの資料を探して、問題を解決しました.ref: http://www.cnblogs.com/pengineer/p/5011965.html
問題と現象:
タスクは完了しましたが、スレッドプール内のスレッドは回収されず、プログラムは実行中です.しかし、ThreadPoolExecutorのパラメータにタイムアウト時間が設定されているのは、ワークスレッドの回収には3つの条件を満たす必要があるため、役に立たないようです.パラメータallowCoreThreadTimeOutはtrue このスレッドはkeepAliveTime時間内にタスクを取得できない、すなわち、こんなに長い時間空いている である.現在のスレッドプールサイズ>コアスレッドプールサイズcorePoolSize.
解決1:allowCoreThreadTimeOutをtrueに設定
注意しなければならないのは、allowCoreThreadTimeOutの設定は、タスクの実行前に、一般的にnewのスレッドプールの後に設定する必要があります.allowCoreThreadTimeOutがtrueに設定されている場合、ThreadPoolExecutorのkeepAliveTimeパラメータは0より大きくなければなりません.
解決2:shutdownメソッドの呼び出し
タスクの実行が完了したら、shutdownメソッドを呼び出し、スレッドプール内の空きスレッドを回収します.この方法はkeepAliveTimeパラメータを無効にする.
スレッドプール内のすべてのタスクが実行されると、スレッドは停止せず、JVMにOOMの問題が発生します.その後、次のリンクの資料を探して、問題を解決しました.ref: http://www.cnblogs.com/pengineer/p/5011965.html
問題と現象:
public static void main(String[] args) {
BlockingQueue queue = new LinkedBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 10, TimeUnit.SECONDS, queue);
for (int i = 0; i < 20; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(this.hashCode() / 1000);
for (int j = 0; j < 10; j++) {
System.out.println(this.hashCode() + ":" + j);
Thread.sleep(this.hashCode() % 2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("thread %d finished", this.hashCode()));
}
});
}
}
タスクは完了しましたが、スレッドプール内のスレッドは回収されず、プログラムは実行中です.しかし、ThreadPoolExecutorのパラメータにタイムアウト時間が設定されているのは、ワークスレッドの回収には3つの条件を満たす必要があるため、役に立たないようです.
解決1:allowCoreThreadTimeOutをtrueに設定
public static void method1() {
BlockingQueue queue = new LinkedBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue);
executor.allowCoreThreadTimeOut(true);
for ( int i = 0; i < 20; i++) {
executor.execute( new Runnable() {
public void run() {
try {
System. out.println( this.hashCode()/1000);
for ( int j = 0; j < 10; j++) {
System. out.println( this.hashCode() + ":" + j);
Thread. sleep(this.hashCode()%2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System. out.println(String. format("thread %d finished", this.hashCode()));
}
});
}
}
注意しなければならないのは、allowCoreThreadTimeOutの設定は、タスクの実行前に、一般的にnewのスレッドプールの後に設定する必要があります.allowCoreThreadTimeOutがtrueに設定されている場合、ThreadPoolExecutorのkeepAliveTimeパラメータは0より大きくなければなりません.
解決2:shutdownメソッドの呼び出し
public static void method1() {
BlockingQueue queue = new LinkedBlockingQueue();
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.SECONDS, queue);
for ( int i = 0; i < 20; i++) {
executor.execute( new Runnable() {
public void run() {
try {
System. out.println( this.hashCode()/1000);
for ( int j = 0; j < 10; j++) {
System. out.println( this.hashCode() + ":" + j);
Thread. sleep(this.hashCode()%2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System. out.println(String. format("thread %d finished", this.hashCode()));
}
});
}
executor.shutdown();
}
タスクの実行が完了したら、shutdownメソッドを呼び出し、スレッドプール内の空きスレッドを回収します.この方法はkeepAliveTimeパラメータを無効にする.