016.多線程-線程池的四種創建方式

版權聲明:本文爲博主原創文章,允許轉載,請標明出處。 https://blog.csdn.net/qwdafedv/article/details/84256291

前言

爲什麼要用線程池

經常創建、銷燬 線程,將是對系統資源的極大浪費。 因此,實際開發中我們將使用線程池來管理、複用 線程。 使用線程池,可以 1.降低資源消耗: 重複利用線程,減少創建和銷燬造成的消耗。 2.提升響應速度: 任務到達,不需要創建,立即執行。 3.提高可管理型: 線程是CPU調度和分派的基本單位, 如果無限制地創建,不僅會消耗系統資源,還會降低系統穩定性。 使用線程池可以統一進行 分配、調優和監控。

線程池的分類

ThreadPoolExecutor

ThreadPoolExecutor是線程池的真正實現, 他通過構造方法的一系列參數,來構成不同配置的線程池。 常用的構造方法有下面四個

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler);
  • corePoolSize: 核心池的大小。 當有任務來之後,就會創建一個線程去執行任務,當線程池中的線程數目達到corePoolSize後,就會把到達的任務放到緩存隊列當中
  • maximumPoolSize: 線程池最大線程數,它表示在線程池中最多能創建多少個線程;
  • keepAliveTime: 表示線程沒有任務執行時最多保持多久時間會終止。
  • unit: 參數keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態屬性。
  • workQueue:一個阻塞隊列,提交的任務將會被放到這個隊列裏。
  • threadFactory:線程工廠,用來創建線程,主要是爲了給線程起名字,默認工廠的線程名字:pool-1-thread-3。
  • handler:拒絕策略,當線程池裏線程被耗盡,且隊列也滿了的時候會調用。

線程池的四種創建方式

Java通過Executors(jdk1.5併發包)提供四種線程池,分別爲:

  • newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。 案例演示:
  • newFixedThreadPool 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
  • newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行。
  • newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。

newCachedThreadPool

創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程, 若無可回收,則新建線程。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test111907 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp);
                }
            });
        }
    }
}
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newFixedThreadPool

創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test111907 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp);
                }
            });
        }
    }
}
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

newScheduledThreadPool

創建一個定長線程池,支持定時及週期性任務執行。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test111907 {
    public static void main(String[] args) {
        final long begin = System.currentTimeMillis();
        ExecutorService executorService = Executors.newScheduledThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            final long time = begin;
            executorService.schedule(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp + "   time=" + (System.currentTimeMillis() - time));
                }
            }, 5, TimeUnit.SECONDS);
        }
    }
}
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
              new DelayedWorkQueue());
    }

newSingleThreadExecutor

創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務, 保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test111907 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp);
                }
            });
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章