あなたが持っていると仮定しましょうOdbcCaller
:
public class OdbcCaller {
public void callODBC() {
// call ODBC directly
// ...
}
実行可能なタスクでラップし、タスクをスレッドプールに送信して、非同期で実行することができます。
public void asyncCallODBC() {
// wrap the call with a runnable task
executor.execute(new Runnable() {
@Override
public void run() {
callODBC();
}
});
// the above line would return immediately.
}
これexecutor
はJDKによって提供されるスレッドプールの実装であり、次のように定義できます。
Executor executor = new ThreadPoolExecutor(/* core pool size */5,
/* maximum pool size */10,
/* keepAliveTime */1,
/* time unit of keepAliveTime */TimeUnit.MINUTES,
/* work queue */new ArrayBlockingQueue<Runnable>(10000),
/* custom thread factory */new ThreadFactory() {
private AtomicInteger counter = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "asyncCaller-" + (counter.incrementAndGet()));
return t;
}
},
/*
* policy applied when all tasks are occupied and task
* queue is full.
*/new ThreadPoolExecutor.CallerRunsPolicy());
はThreadPoolExecutor
高度に構成可能であり、JavaDocで十分に文書化されているため、最初に読むことをお勧めします。
以下は、私の経験に基づいたスレッドプール構成のいくつかの提案です。
- 適切なスレッドプールサイズはシナリオによって異なります。調整するためにいくつかのテストを実行する必要がある場合があります。
- 使用可能なワーカースレッドがない場合、ワークキューはタスクをキャッシュするために使用されます。無制限のキューは、メモリが不足する可能性があるため、お勧めできません。
- を提供し
ThreadFactory
、スレッドに意味のある名前を付けることをお勧めします。jstack
(または他のツールを使用して)スレッドの状態を検査する必要がある場合に非常に役立ちます。
- 拒否ポリシーは、使用可能なリソースがない場合に適用されます。組み込みポリシー(拒否、破棄、呼び出し元実行、discardOldest)のいずれかを選択するか、独自のポリシーを実装できます。