6、java5線程池之固定大小線程池newFixedThreadPool


 

JDK文檔說明:

創建一個可重用固定線程數的線程池,以共享的無界隊列方式來運行這些線程。在任意點,在大多數 nThreads 線程會處於處理任務的活動狀態。如果在所有線程處於活動狀態時提交附加任務,則在有可用線程之前,附加任務將在隊列中等待。如果在關閉前的執行期間由於失敗而導致任何線程終止,那么一個新線程將代替它執行后續的任務(如果需要)。在某個線程被顯式地關閉之前,池中的線程將一直存在。

 創建方法:

java.util.concurrent.Executors.newFixedThreadPool(int nThreads) 

or

java.util.concurrent.Executors.newFixedThreadPool(int nThreads, ThreadFactory threadFactory) 

 

調用上面2個方法得到的對象為:ExecutorService

JDK自帶的例子:

下面給出了一個網絡服務的簡單結構,這里線程池中的線程作為傳入的請求。它使用了預先配置的 Executors.newFixedThreadPool(int) 工廠方法:

class NetworkService implements Runnable {
    private final ServerSocket serverSocket;
    private final ExecutorService pool;

    public NetworkService(int port, int poolSize)  throws IOException {
      serverSocket = new ServerSocket(port);
      pool = Executors.newFixedThreadPool(poolSize);
    }
 
    public void run() { // run the service
      try {
        for (;;) {
          pool.execute(new Handler(serverSocket.accept()));
        }
      } catch (IOException ex) {
        pool.shutdown();
      }
    }
  }

class Handler implements Runnable {
    private final Socket socket;
    Handler(Socket socket) { this.socket = socket; }
    public void run() {
      // read and service request on socket
    }
}

 

主要的方法:

 
boolean awaitTermination(long timeout, TimeUnit unit)
請求關閉、發生超時或者當前線程中斷,無論哪一個首先發生之后,都將導致阻塞,直到所有任務完成執行。
<T> List<Future<T>>  invokeAll(Collection<? extends Callable<T>> tasks)
執行給定的任務,當所有任務完成時,返回保持任務狀態和結果的 Future 列表。
<T> List<Future<T>>
invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
執行給定的任務,當所有任務完成或超時期滿時(無論哪個首先發生),返回保持任務狀態和結果的 Future 列表。
<T> T
invokeAny(Collection<? extends Callable<T>> tasks)
執行給定的任務,如果某個任務已成功完成(也就是未拋出異常),則返回其結果。
<T> T
invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
執行給定的任務,如果在給定的超時期滿前某個任務已成功完成(也就是未拋出異常),則返回其結果。
boolean isShutdown()
如果此執行程序已關閉,則返回 true
boolean isTerminated()
如果關閉后所有任務都已完成,則返回 true
void shutdown()
啟動一次順序關閉,執行以前提交的任務,但不接受新任務。
List<Runnable> shutdownNow()
試圖停止所有正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的任務列表。
<T> Future<T>
submit(Callable<T> task)
提交一個返回值的任務用於執行,返回一個表示任務的未決結果的 Future。
Future<?> submit(Runnable task)
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。
<T> Future<T>

submit(Runnable task, T result)
提交一個 Runnable 任務用於執行,並返回一個表示該任務的 Future。

void

execute(Runnable command)
在未來某個時間執行給定的命令。

 

自己寫的例子:

 

package com.yzl;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ThreadPool {
    public static void main(String[] args) {
        fixedThreadPool();
    }
    
    /**
     * 固定大小的線程池
     * 
     * 同時可以處理【參數】個任務,多余的任務會排隊,當處理完一個馬上就會去接着處理排隊中的任務。
     * Callable的任務在后面的blog有更詳細的文章說明
     */
    private static void fixedThreadPool(){
        ExecutorService es = Executors.newFixedThreadPool(2);
        //加入5個任務
        for(int i=1 ; i<5; i++){
            final int task = i;
            es.execute(new Runnable() {
                @Override
                public void run() {
                    for(int j=1; j<=2; j++){
                        System.out.println("現在運行的是第【 " + task + "】任務");
                        System.out.println(Thread.currentThread().getName() + "is work , now loop to " + j);
                        if(j==2){
                            System.out.println("任務 【" + task + "】運行完成");
                        }
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
        System.out.println("5個Runnable任務submit完成!!");

        //加入5個Callable任務,該任務執行完后是有返回值的則會發生堵塞,也就是取到5個任務的結果后才會繼續往下走
        for(int i=1 ; i<=5; i++){
            final int task = i;
            Future<Integer> future = es.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Callable 任務【" + task + "】運行");
                    return new Random().nextInt(100);
                }
            });
            
            //如果注釋取結果的代碼,則不會堵塞
            /*try {
                System.out.println("任務【" + i + "】返回的結果:" + future.get());
            } catch (Exception  e) {
                e.printStackTrace();
            }*/
        }    
        System.out.println("5個Callable任務submit完成!!" + System.currentTimeMillis() );
        //雖然shutdown方法是等所有任務跑完后才真正停掉線程池,但該方法不會造成堵塞,也就是這代碼運行后,下一行代碼會立刻運行
        es.shutdown();
        System.out.println("主程序shutdown后退出!!" + System.currentTimeMillis());
        
        //暴力的直接終止線程池
        //es.shutdownNow();
        
        //awaitTermination方法是堵塞式的,只有等真的把線程池停掉才會讓程序繼續往下執行
        try {
            es.awaitTermination(2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("主程序后awaitTermination退出!!" + System.currentTimeMillis());
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM