2017年2月28日 星期二

三種啟動 Thread 的方法 (Thread 二)

Thread 有 8 個建構子,此篇使用到以下 4 個
Thread():預設建構子,名稱是 Thread-Number
Thread(String):給 Thread 名稱
Thread(Runnable):給Runnable 物件
Thread(Runnable, String):給Runnable 物件,並給 Thread 名稱


※Thread

public class ThreadTest1 extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
    
    public static void main(String... a) {
        ThreadTest1 t1 = new ThreadTest1();
        t1.start();
        Thread t2 = new Thread(t1);
        t2.start();
        Thread t3 = new Thread(t1, "xxx");
        t3.start();
    
        new Thread("xxx") {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName());
            }
    
        }.start();
    }
}

※最後是匿名寫法



※Runnable

Runnable 是個介面,因為 Thread 是 class,如果自己寫的 class 已經繼承了某個類別,那 java 就不允許再繼承了,所以可以使用 Runnable


public class ThreadTest2 implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
    
    public static void main(String... a) {
        ThreadTest2 t1 = new ThreadTest2();
        // t1.start();
        Thread t2 = new Thread(t1);
        t2.start();
        Thread t3 = new Thread(t1, "xxx");
        t3.start();
    
        new Thread(t1, "xxx") {
            @Override
            public void run() {
                System.out.println("t1:" + Thread.currentThread().getName());
            }
        }.start();
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Runnable:" + Thread.currentThread().getName());
            }
        }, "ooo").start();
    
        // Java 8 的 lambda 寫法,這樣子 ThreadTest2 可以不用 implements 了
        new Thread(() -> System.out.println("t1:" + Thread.currentThread().getName()), "xxx").start();
    }
}

※最後兩個是匿名寫法

※Runnable 並沒有start(),所以註解打開會編譯錯誤



※Callable

此種方式是 java 1.5 增加的,實作 Runnable 要寫 run 方法;而實作 Callable 要寫 call 方法
call 有例外有返回值;run 都沒有


import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
    
public class ThreadTest3 implements Callable<String> {
    @Override
    public String call() throws Exception {
        return Thread.currentThread().getName();
    }
    
    public static void main(String... a) {
        ExecutorService service = Executors.newFixedThreadPool(1);
        Future<String> future = service.submit(new ThreadTest3());
    
        // Java 8 的 lambda 寫法,這樣子 ThreadTest3 可以不用 implements 了
        // Future<String> future = service.submit(() -> Thread.currentThread().getName());
    
        try {
            String s = future.get();
            System.out.println("s=" + s); // pool-1-thread-1
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    
        List<Runnable> list = service.shutdownNow();
        System.out.println(list.size());
//        service.shutdown();
    }
}





※Callable 的匿名寫法

public class ThreadTest3 {
    public static void main(String... a) {
        ExecutorService service = Executors.newFixedThreadPool(1);
        Future<String> future = service.submit(new Callable<String>() {
            @Override
            public String call() {
                return Thread.currentThread().getName();
            }
        });
    
        try {
            String s = future.get();
            System.out.println("s=" + s);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    
        List<Runnable> list = service.shutdownNow();
        System.out.println(list.size());
        // service.shutdown();
    }
}

※shutdown() 或 shutdownNow() 不寫也不會錯,但Eclipse裡的console,有個Terminate(正方形)會變成紅色的,表示未結束,所以要加這兩個其中之一



※shutdown() 和 shutdownNow() 的區別

shutdown 會執行完 Runnable 後才關閉
shutdownNow 會馬上關閉,還沒執行的 Runnable 以 List<Runnable> 傳回。

沒有留言:

張貼留言