開啓多線程的三種方式

一 .繼承Thread類

simple:

public class test01 {

    @Test
    public void thread01(){
        for(int i = 0; i < 10; i++){
            Business business = new Business();
            Thread thread = new Thread(business);
            thread.start();
        }

    }
    class Business extends Thread{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
}

result : 

PS : 

1. java是單繼承,所以用繼承Thread實現多線程必須確保該類不繼承其他類

 

二.實現Runnable接口

simple:

public class test02 {

    @Test
    public void thread02(){
        for(int i = 0; i < 10; i++){
            Business business = new Business();
            Thread thread = new Thread(business);
            thread.start();
        }

    }
    class Business implements Runnable{

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
}

result : 

PS:

1.實現Runnable接口得到的結果與直接使用Thread得到的結果無異。

2.實現runnable實現多線程,沒有返回值,核心方法爲run方法,不能拋出異常

3.Runnable實現多線程沒有返回值,若需要做數據統計可使用Callable實現多線程,若情況特殊可參考《實現Runnable的多線程數據統計》

三.實現Callable接口(兩種方式)

1).用FutureTask實現

simple:

public class test04 {

    @Test
    public void thread04() throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newCachedThreadPool();
        List<FutureTask> futureTasks = new ArrayList<>();
        for(int i = 0;i < 10; i++){
            Business business = new Business("hello" + i);
            FutureTask task = new FutureTask(business);
            executor.execute(task);
            futureTasks.add(task);
        }
        for(FutureTask future:futureTasks){
            System.out.println(future.get());
        }
    }
    class Business implements Callable<String>{

        private String threadStr;

        Business(String str){
            this.threadStr = str;
        }
        @Override
        public String call() throws Exception {
            Thread.sleep(1000);
            return Thread.currentThread().getName() + " say:" + threadStr;
        }
    }
}

result :

 

2).用Future實現

simple:

public class test03 {

    @Test
    public void thread03() throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<Future> futures = new ArrayList<>();
        for(int i = 0;i < 10; i++){
            Business business = new Business("hello" + i);
            Future<String> future = executor.submit(business);
            futures.add(future);
        }
        for(Future future:futures){
            System.out.println(future.get());
        }
    }
    class Business implements Callable<String>{

        private String threadStr;

        Business(String str){
            this.threadStr = str;
        }
        @Override
        public String call() throws Exception {
            Thread.sleep(1000);
            return Thread.currentThread().getName() + " say:" + threadStr;
        }
    }
}

 

result:

PS :

1.callable<V>可以擁有返回值,所以一般用來統計或計算,核心方法爲call方法,可以拋出異常。

2.不要直接在子線程未啓動完之前get(),否則就與單線程無異。

3.儘量配合使用線程池,雖然FutureTask也可以作爲Runnable傳到Thread()中.

4.使用ExecutorService創建線程池請參考《線程池詳解》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章