1. 程式人生 > >java 創建線程池的4中方式

java 創建線程池的4中方式

java 創建線程池的4中方式

Java線程池使用說明

線程池的作用:
線程池作用就是限制系統中執行線程的數量。
根據系統的環境情況,可以自動或手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用線程池控制線程數量,其他線程排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待進程,線程池的這一資源處於等待。當一個新任務需要運行時,如果線程池中有等待的工作線程,就可以開始運行了;否則進入等待隊列。

java中常用線程池

  1. newSingleThreadExecutor
    創建一個單線程的線程池。這個線程池只有一個線程在工作,也就是相當於單線程串行執行所有任務。如果這個唯一的線程因為異常結束,那麽會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行。
    2.newFixedThreadPool
    創建固定大小的線程池。每次提交一個任務就從線程池中拿一個線程,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那麽線程池會補充一個新線程。
    1. newCachedThreadPool
      創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程,
      那麽就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴於操作系統(或者說JVM)能夠創建的最大線程大小。
      4.newScheduledThreadPool
      創建一個支持定時以及周期性執行任務的線程池。多數情況下可用來替代Timer類

單線程線程池 Executors.newSingleThreadExecutor()

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

public class Chi {
    public static void main(String[] args) {
        /*沒有線程池的寫法
        Runnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();*/

ExecutorService e =Executors.newSingleThreadExecutor();//創建一個單線程的線程池
        e.submit(new MyRunnable());
        e.submit(new MyRunnable());
        e.submit(new MyRunnable());
        e.submit(new MyRunnable());
        e.submit(new MyRunnable());
        e.submit(new MyRunnable());
        e.shutdown();
    }
    }

class MyRunnable implements Runnable{
@Override
    public void run() {
        System.out.println("給我一個線程:"+Thread.currentThread().getName());
        try {
            System.out.println("線程開始消耗資源"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("線程使用完畢"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("歸還到線程池中"+Thread.currentThread().getName());
    }
    }

運行結果
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1

創建一個固定長度的線程池 Executors.newFixedThreadPool()

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

public class Chi {
    public static void main(String[] args) {
        /*沒有線程池的寫法
        Runnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();*/

ExecutorService e =Executors.newFixedThreadPool(2);//創建一個包含兩個線程的線程池
        Runnable r = new MyRunnable();
        e.submit(r);//獲取線程池中的某一個線程對象,然後調用runnable接口中的run方法
        e.submit(r);
        e.submit(r);
        e.submit(r);//註意run方法運行完,線程中的線程並不消耗,而是歸還到池中
        e.shutdown();
    }
    }

class MyRunnable implements Runnable{
@Override
    public void run() {
        System.out.println("給我一個線程:"+Thread.currentThread().getName());
        try {
            System.out.println("線程開始消耗資源"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("線程使用完畢"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("歸還到線程池中"+Thread.currentThread().getName());
    }
    }

運行結果
給我一個線程:pool-1-thread-1
給我一個線程:pool-1-thread-2
線程開始消耗資源pool-1-thread-1
線程開始消耗資源pool-1-thread-2
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
線程使用完畢pool-1-thread-2
給我一個線程:pool-1-thread-1
線程開始消耗資源pool-1-thread-1
歸還到線程池中pool-1-thread-2
給我一個線程:pool-1-thread-2
線程開始消耗資源pool-1-thread-2
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-1
線程使用完畢pool-1-thread-2
歸還到線程池中pool-1-thread-2

創建一個可緩存的線程池

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

public class Chi {
    public static void main(String[] args) {
        /*沒有線程池的寫法
        Runnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();*/
        ExecutorService e =Executors.newCachedThreadPool();
        Runnable r = new MyRunnable();
        e.submit(r);//獲取線程池中的某一個線程對象,然後調用runnable接口中的run方法
        e.submit(r);
        e.submit(r);
        e.submit(r);//註意run方法運行完,線程中的線程並不消耗,而是歸還到池中
        e.shutdown();
    }
    }

class MyRunnable implements Runnable{
@Override
    public void run() {
        System.out.println("給我一個線程:"+Thread.currentThread().getName());
        try {
            System.out.println("線程開始消耗資源"+Thread.currentThread().getName());
            Thread.sleep(2000);
            System.out.println("線程使用完畢"+Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("歸還到線程池中"+Thread.currentThread().getName());
    }
    }

運行結果
給我一個線程:pool-1-thread-1
給我一個線程:pool-1-thread-4
給我一個線程:pool-1-thread-3
給我一個線程:pool-1-thread-2
線程開始消耗資源pool-1-thread-3
線程開始消耗資源pool-1-thread-4
線程開始消耗資源pool-1-thread-1
線程開始消耗資源pool-1-thread-2
線程使用完畢pool-1-thread-2
線程使用完畢pool-1-thread-3
線程使用完畢pool-1-thread-4
線程使用完畢pool-1-thread-1
歸還到線程池中pool-1-thread-4
歸還到線程池中pool-1-thread-2
歸還到線程池中pool-1-thread-3
歸還到線程池中pool-1-thread-1

創建一個可緩存並且可以周期性執行任務的線程池

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Chi {
    public static void main(String[] args) {
        /*沒有線程池的寫法
        Runnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();*/
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ScheduledThreadPoolExecutor e = new ScheduledThreadPoolExecutor(3);//參數表示線程容量
        System.out.println(simpleDateFormat.format(new Date()));
        // 但是如果執行任務時間大約2s則不會並發執行後續任務將會延遲。
        ScheduledFuture<?> resultFuture = e.scheduleAtFixedRate(new MyRunnable(), 0, 2000, TimeUnit.MILLISECONDS);//第一個參數任務,第二個參數表示執行任務前等待的時間,第三個參數表示任務啟動間隔時間,第四參數表示時間單位
        e.scheduleAtFixedRate(new MyRunnable1(), 0, 2000, TimeUnit.MILLISECONDS);//第一個參數任務,第二個參數表示執行任務前等待的時間,第三個參數表示任務啟動間隔時間,第四參數表示時間單位
        // // 由於是定時任務,一直不會返回
        //Object object = resultFuture.get();
    }
}

class MyRunnable implements Runnable{
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"給我一個線程:"+simpleDateFormat.format(new Date()));
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class MyRunnable1 implements Runnable{
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"給我一個線程1:"+simpleDateFormat.format(new Date()));
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

運行結果
2018-03-17 13:48:05
pool-1-thread-1給我一個線程:2018-03-17 13:48:05
pool-1-thread-2給我一個線程1:2018-03-17 13:48:05
pool-1-thread-1給我一個線程:2018-03-17 13:48:07
pool-1-thread-1給我一個線程:2018-03-17 13:48:09
pool-1-thread-3給我一個線程:2018-03-17 13:48:11
pool-1-thread-3給我一個線程:2018-03-17 13:48:13
pool-1-thread-2給我一個線程1:2018-03-17 13:48:15
pool-1-thread-3給我一個線程:2018-03-17 13:48:15
pool-1-thread-3給我一個線程:2018-03-17 13:48:17
pool-1-thread-3給我一個線程:2018-03-17 13:48:19
pool-1-thread-1給我一個線程:2018-03-17 13:48:21
pool-1-thread-1給我一個線程:2018-03-17 13:48:23
pool-1-thread-3給我一個線程1:2018-03-17 13:48:25
pool-1-thread-1給我一個線程:2018-03-17 13:48:25
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

java 創建線程池的4中方式