Executor框架
Executor基於生產者-消費者模式,提交任務的操作相當於生產者(生成待完成的工作單元),執行任務的線程則相當於消費者(執行完這些工作單元)。它提供了一種標準的方法將任務的提交和過程與執行過程解耦開來。
幾種線程池(ExecutorService)
newFixedThreadPool-固定長度線程池,每提交一個任務創建一個線程。
示例代碼:
public class FixedThreadPoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executorService.submit(new MyRunnable((i + 1) * 5));
}
executorService.shutdown();
}
private static class MyRunnable implements Runnable {
private int sleepSec;
public MyRunnable(int sleepSec) {
this.sleepSec = sleepSec;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " will run for " + sleepSec + "s");
try {
SECONDS.sleep(sleepSec);
System.out.println(Thread.currentThread().getName() + " is done!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
newCachedThreadPool-可緩存線程池,線程池規模不受限制。
示例代碼:
public class CachedThreadPoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
executorService.submit(new MyRunnable((i + 1) * 5));
}
executorService.shutdown();
}
private static class MyRunnable implements Runnable {
private int sleepSec;
public MyRunnable(int sleepSec) {
this.sleepSec = sleepSec;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " will run for " + sleepSec + "s");
try {
SECONDS.sleep(sleepSec);
System.out.println(Thread.currentThread().getName() + " is done!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
newSingleThreadExecutor-單線程Executor,創建單個工作者線程來執行任務。
示例代碼:
public class SingleThreadPoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
executorService.submit(new MyRunnable((i + 1) * 5));
}
executorService.shutdown();
}
private static class MyRunnable implements Runnable {
private int sleepSec;
public MyRunnable(int sleepSec) {
this.sleepSec = sleepSec;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " will run for " + sleepSec + "s");
try {
SECONDS.sleep(sleepSec);
System.out.println(Thread.currentThread().getName() + " is done!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
newScheduledThreadPool-固定長度線程池,且以延遲或定時的方式來執行任務,類似Timer。
示例代碼:Timer與ScheduledExecutorService比較
public class OutofTime {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
timer.schedule(new ThrowTask(), 1);
SECONDS.sleep(1);
timer.schedule(new ThrowTask(), 5);
SECONDS.sleep(5);
}
static class ThrowTask extends TimerTask {
@Override
public void run() {
System.out.println("Ah...");
throw new RuntimeException();
}
}
}
public class InTime {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.schedule(new ThrowTask(), 1, TimeUnit.SECONDS);
SECONDS.sleep(1);
executor.schedule(new ThrowTask(), 5, TimeUnit.SECONDS);
SECONDS.sleep(5);
executor.shutdown();
}
static class ThrowTask implements Runnable {
@Override
public void run() {
System.out.println("Ah....");
throw new RuntimeException();
}
}
}
參考:《Java併發編程實戰》