程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java多線程系列4-線程池,java多線程4-線程

java多線程系列4-線程池,java多線程4-線程

編輯:JAVA綜合教程

java多線程系列4-線程池,java多線程4-線程


在之前的文章中,學習了通過實現java.lang.Runnable來定義類,以及像下面這樣創建一個線程來運行任務:

Runnable task = new TaskClass(task);

new Thread(task).start();

該方法對單一任務是很方便,但是對於大量的任務而言是不夠高效的。為每一個任務開始一個新的線程可能會限制流量並且造成性能降低。

java提供Executor接口來執行線程池中的任務,提供ExecutorService 接口來管理和控制任務,ExecutorService 接口是Executor接口的子接口

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads)

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

參數:nThreads - 池中的線程數

返回:新創建的線程池

拋出:IllegalArgumentException - 如果 nThreads <= 0

newCachedThreadPool

public static ExecutorService newCachedThreadPool()

創建一個可根據需要創建新線程的線程池,但是在以前構造的線程可用時將重用它們。對於執行很多短期異步任務的程序而言,這些線程池通常可提高程序性能。調用 execute 將重用以前構造的線程(如果線程可用)。如果現有線程沒有可用的,則創建一個新線程並添加到池中。終止並從緩存中移除那些已有 60 秒鐘未被使用的線程。因此,長時間保持空閒的線程池不會使用任何資源。注意,可以使用 ThreadPoolExecutor 構造方法創建具有類似屬性但細節不同(例如超時參數)的線程池。

返回:新創建的線程池

看一個多線程的例子:

package ExecuterTest;
 
public class TaskThreadDemo {
 
    public static void main(String[] args) {
        //新建任務與線程
        Thread th1 = new Thread(new PrintChar('a', 100));
        Thread th2 = new Thread(new PrintChar('b', 100));
        Thread th3 = new Thread(new PrintNum(100));
        
        //啟動線程
        th1.start();
        th2.start();
        th3.start();
    }
 
}
//任務為:打印指定字符的指定次數
class PrintNum implements Runnable {
    private int lastNum;
    
    public PrintNum(int n) {
        lastNum = n;
    }
 
    @Override
    public void run() {
        for (int i = 1; i <= lastNum; i++) {
            System.out.println(" " + i);
 
        }
 
    }
}
//任務為:打印從1-n的所有數
class PrintChar implements Runnable {
 
    private char charToPrint; //打印的字符
    private int times;    //打印的次數
 
    public PrintChar(char c, int t) {
        charToPrint = c;
        times = t;
    }
 
    @Override
    public void run() {
        for (int i = 0; i < times; i++) {
            System.out.println(charToPrint);
        }
    }
}

下面使用線程池來修改上面的程序:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TaskThreadDemo {
    public static void main(String[] args) {    
        //創建了一個最大線程數為3的線程池
        ExecutorService excutor=Executors.newFixedThreadPool(3);
        
        //提交runnable()任務到excutor
        excutor.execute(new PrintChar('a', 100));
        excutor.execute(new PrintChar('b', 100));
        excutor.execute(new PrintNum(100));
        
        //關閉excutor
        excutor.shutdown();
    }
}

如果將第6行改為:

ExecutorService excutor=Executors.newFixedThreadPool(1);

那麼線程池中就只有一個線程,則三個線程將順序執行

如果將第6行改為:

ExecutorService excutor=Executors.newCachedThreadPool();

所有的線程將並發執行

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved