プログラムプール(Executors)
5017 ワード
Javaクラスライブラリでは、タスク実行の主な抽象はThreadではなくExecutorであり、タスクのコミットプロセスと実行プロセスをデカップリングします.
実行サービスのライフサイクルの問題を解決するために、ExecutorはExecutorServiceインタフェースを拡張しました.
ExecutorServiceのライフサイクルは3つのステータスで、実行、停止、終了しています. shutdownは緩やかなクローズプロセスを実行する:新しいタスクを受け入れず、コミットされたタスクの実行が 完了するのを待つ shutdownNowメソッドは、すべての実行中のタスクをキャンセルしようとし、キュー内でまだ実行が開始されていないタスク を起動しない乱暴なクローズ方法を実行します.は、awaitTerminationを呼び出してExecutorServiceが終了状態に達するのを待つか、isTerminatedを呼び出すことによってExecutorServiceが終了したかどうかをポーリングすることができる .
スレッドプール:
新FixedThreadPool:一定長のスレッドプールを作成し、タスクをコミットするたびにスレッドを作成し、スレッドプールの最大数を知る(スレッドが予期せぬExceptionで終了した場合、スレッドプールは新しいスレッドを補充する)
NewCachedThreadPool:処理要件を超えるスレッドプールを作成すると、空きスレッドが回収され、要件が増加すると、新しいスレッドが追加され、スレッドプールの規模に制限はありません.
新SingleThreadExecutor:単一スレッドのExecutor、このスレッドが終了すると新しいスレッドが作成され、キュー内の順序で実行されることを保証します.
新ScheduledThreadPool:固定長スレッドプールを作成し、Timerの代わりに遅延またはタイミングでタスクを実行します.
RunnableとCallableは抽象的な計算タスクを記述しており、後者は戻り値があり、異常を投げ出す可能性がある.
Executorが実行するタスクには、作成、コミット、開始、完了の4つのライフサイクルフェーズがあります.
ExecutorServiceのすべてのsubmitメソッド豆乳はFutureに戻ります.
CallableとFutureインタフェース
CompletionServiceパッケージ用
public interface Executor {
void execute(Runnable command);
}
public class RunMain implements Executor{
@Override
public void execute(Runnable command) {
new Thread(command).start();
}
}
実行サービスのライフサイクルの問題を解決するために、ExecutorはExecutorServiceインタフェースを拡張しました.
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
// ....
}
スレッドプール:
新FixedThreadPool:一定長のスレッドプールを作成し、タスクをコミットするたびにスレッドを作成し、スレッドプールの最大数を知る(スレッドが予期せぬExceptionで終了した場合、スレッドプールは新しいスレッドを補充する)
NewCachedThreadPool:処理要件を超えるスレッドプールを作成すると、空きスレッドが回収され、要件が増加すると、新しいスレッドが追加され、スレッドプールの規模に制限はありません.
新SingleThreadExecutor:単一スレッドのExecutor、このスレッドが終了すると新しいスレッドが作成され、キュー内の順序で実行されることを保証します.
新ScheduledThreadPool:固定長スレッドプールを作成し、Timerの代わりに遅延またはタイミングでタスクを実行します.
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
public class TestScheduledThread {
public static void main(String[] args) {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
final Runnable beeper = new Runnable() {
int count = 0;
public void run() {
System.out.println(new Date() + " beep " + (++count));
}
};
// 1 , 2
final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 1, 2, SECONDS);
// 2 , 5
final ScheduledFuture beeperHandle2 = scheduler.scheduleWithFixedDelay(beeper, 2, 5, SECONDS);
// 30 , Scheduler
scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);
beeperHandle2.cancel(true);
scheduler.shutdown();
}
}, 30, SECONDS);
}
}
RunnableとCallableは抽象的な計算タスクを記述しており、後者は戻り値があり、異常を投げ出す可能性がある.
Executorが実行するタスクには、作成、コミット、開始、完了の4つのライフサイクルフェーズがあります.
ExecutorServiceのすべてのsubmitメソッド豆乳はFutureに戻ります.
CallableとFutureインタフェース
public interface Callable<V> {
V call() throws Exception;
}
public interface Future<V> {
/**
* ,
* , mayInterruptIfRunning
*
* , isDone true。
* isCancelled true
*
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* , 。 true
*/
boolean isCancelled();
boolean isDone();
/**
* ,
* @throws CancellationException
* if the computation was cancelled
* @throws ExecutionException
* if the computation threw an exception
* @throws InterruptedException
* if the current thread was interrupted while waiting
*/
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
CompletionServiceパッケージ用
public class RunMain implements Callable<String> {
private int id;
public RunMain(int i) {
this.id = i;
}
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newCachedThreadPool();
CompletionService<String> completion = new ExecutorCompletionService<String>(service);
for (int i = 0; i < 10; i++) {
completion.submit(new RunMain(i));
}
for (int i = 0; i < 10; i++) {
System.out.println(completion.take().get());
}
service.shutdown();
}
public String call() throws Exception {
Integer time = (int) (Math.random() * 1000);
try {
System.out.println(this.id + " start");
Thread.sleep(time);
System.out.println(this.id + " end");
} catch (Exception e) {
e.printStackTrace();
}
return this.id + ":" + time;
}
}