天天看點

建立線程之實作Callable接口和線程池

建立線程的方法總的有四種方法,之前我提過前兩種一個是繼承Thread方法一個是實作Runnable接口方法 現在我們接着講第三種實作Callable接口和第四種線程池

1.建立一個實作Callable接口的實作類

2.實作call方法

3.建立Callable接口實作類的對象

4.将此接口實作類作為參數傳遞到FutureTask構造器中

5.将FutureTask的對象作為參數傳遞到Thread類的構造器中,建立Thread對象,并調用start()

實作代碼如下:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 建立線程的第三種方法
 * 實作Callable接口  jdk5.0新增
 * 步驟
 * 1.建立一個實作類Callable的實作類
 * 2.實作Call方法
 * 3.建立Callable實作類接口的對象
 * 4.将此Callable接口實作類對象作為參數傳遞到FutureTask構造器中
 * 5.将FutureTask的對象作為參數傳遞到Thread類的構造器中,建立Thread對象,并調用start()
 * @Author:阿土伯
 * @Date: 2022/1/17 11:40
 * 如何了解實作Callable接口的方式建立多線程比實作Runnable接口建立多線程方式強大?
 * 1.call()可以有傳回值
 * 2.call()可以抛出異常,被外面的操作捕獲,擷取異常資訊
 * 3.Callable是支援泛型的
 */
//1.建立一個實作類Callable的實作類
class NumThread implements Callable{
    //2.實作call方法
    @Override
    public Object call() throws Exception {
        int sum=0;
        for(int i=0;i<=100;i++){
            if(i%2==0){
                System.out.println(i);
                sum+=i;
            }
        }
        return sum;
    }
}

public class ThirdTread {
    public static void main(String[] args){
        //3.建立Callable接口實作類對象
        NumThread numThread = new NumThread();
        //4.将此Callable接口實作類對象作為參數傳遞到FutureTask構造器中
        FutureTask futureTask=new FutureTask(numThread);
        //5.将FutureTask的對象做為參數傳遞到Thread類的構造器中,建立Thread對象,并調用start()
        new Thread(futureTask).start();
        try {
            Object sum = futureTask.get();
            System.out.println("總和為:"+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
           

線程池:

在開發中我們大部分使用線程池來建立線程

代碼如下:

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

/**第四種建立線程的方式:使用線程池 在開發中大部分都是用線程池的方法
 * 背景:經常建立和銷毀、使用量特别大的資源,比如并發情況下的線程
 * 對性能影響很大
 * 思路:提前建立好多個線程,放入線程池中,使用時直接擷取,使用完放回
 * 線程池中。可以避免頻繁建立銷毀、實作重複利用。
 * 好處:
 * 提高響應速度(減少建立新線程的時間)
 * 降低資源消耗(重複利用線程池中的線程,不需要每次都建立)
 * 便于管理線程
 * @Author:阿土伯
 * @Date: 2022/1/17 19:53
 */
class Pools implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<=100;i++){
            if(i%2==0){
                System.out.println(Thread.currentThread().getName()+": "+i);
            }
        }
    }
}
public class ForthThread {
    public static void main(String[] args) {
        //提供指定線程數量的線程池
        ExecutorService service=Executors.newFixedThreadPool(10);
        //設定線程池的屬性

        //2.執行指定的線程的操作。需要提供Runnable接口或Callable接口實作類對象
        service.execute(new Pools());//适合适用Runnable
//        service.submit();//适合适用于Callable
        service.shutdown();
    }
}