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 就不允許再繼承了,所以可以使用 Runnablepublic 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> 傳回。