Java多線程的創建(二)


  • 前言:

    雖然java的API中說創建多線程的方式只有兩種(There are two ways to create a new thread of execution),分別是繼承Thread類創建和實現Runnable接口創建,在上一篇博文中演示了這兩種,詳見,但是JDK5.0以后新增了兩種,分別是實現Callable接口創建和使用線程池創建,本次就演示后兩種創建方式並分析其特性。


  • 實現Runnable接口創建多線程

    創建步驟:

    1.創建一個實現Callable接口的類。

    2.重寫call()方法,線程需要執行的代碼都放到call方法中。

    3.創建實現Callable接口類的實例對象。

    4.將步驟 3 的對象作為參數傳給FutureTask構造器中,創建FutureTask對象。

    5.將FutureTask的對象作為參數傳給Thread類,創建對象並調用start()方法。

package day02;

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

//創建一個多線程,輸出20以內的偶數,並返回所有偶數的和
//1.創建一個實現`Callable`接口的類。  
class TestSum implements Callable{
   //2.重寫call()方法,線程需要執行的代碼都放到call方法中。
    @Override
    public Object call() throws Exception{
        int sum = 0;
        for(int i = 1;i <= 20 ;i++ ){
            if(i % 2 == 0){
                System.out.println(i);
                sum = sum + i;
            }
        }
        return sum;
    }
}

public class ThreadCall {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3.創建實現`Callable`接口類的實例對象。
        TestSum test = new TestSum();
        //4.將步驟 3 的對象作為參數傳給`FutureTask`構造器中,創建`FutureTask`對象。
        FutureTask futuretask = new FutureTask(test);
        //5.將`FutureTask`的對象作為參數傳給`Thread`類,創建對象並調用start()方法。
        Thread thread = new Thread(futuretask);
        thread.start();
        //get方法可以獲取返回值
        System.out.println("偶數總合是:"+futuretask.get());
    }
}
//輸出結果:
2
4
6
8
10
12
14
16
18
20
偶數總合是:110

實現Callable接口創建多線程的特點:

​ 1.call()方法可以有返回值,可以使用get()方法獲取返回值。

​ 2.call()方法可以拋出異常, 而且能被外面捕獲到。

​ 3.Callable支持泛型。


  • 使用線程池創建多線程

    一.實現Runnable接口的方式創建:

package day02;

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

class Number implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

public class ThreadPool {
    public static void main(String[] args){
        ExecutorService service = Executors.newFixedThreadPool(10);
        Number num = new Number();
        service.execute(num);
        service.shutdown();

二.實現Callable接口的方式創建:

package day02;

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

class Number implements Callable {
    @Override
    public Object call() {
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
        return null;
    }
}

public class ThreadPool {
    public static void main(String[] args){
        ExecutorService service = Executors.newFixedThreadPool(10);
        Number num = new Number();
        service.submit(num);//區別在這里
        service.shutdown();
    }
}

  • 線程池好處:

    1.頻繁創建線程和銷毀使用量較大的資源,比如並發的線程,對性能影響較大,所以需要創建線 程池存放線程,使用的時候直接獲取,實現重復利用,提高效率。

    2.降低創建線程時間,提高響應速度。

    3.降低資源的消耗。

    4.便於線程管理。


免責聲明!

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



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