Executor框架與Java線程池

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併發編程實戰》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章