實現線程的三種方式比較
1. 繼承Thread類
1 class ExtendsThread extends Thread{ 2 public void run(){ 3 System.out.println("Thread"); 4 } 5 } 6 public class RunnableDemo { 7 public static void main(String[] args) { 8 Thread thread = new Thread(new ExtendsThread()); 9 thread.start(); 10 } 11 }
2. 實現Runnable接口
1 class RunnableThread implements Runnable{ 2 @Override 3 public void run() { 4 System.out.println("Runnable"); 5 } 6 } 7 public class RunnableDemo { 8 public static void main(String[] args) { 9 Thread thread = new Thread(new RunnableThread()); 10 thread.start(); 11 } 12 }
3. 實現Callable接口(學習線程池的必要前提)
1 class CallableThread implements java.util.concurrent.Callable<Integer>{ 2 //帶返回值 拋異常 3 @Override 4 public Integer call() throws Exception { 5 System.out.println("callable"); 6 return 2048; 7 } 8 } 9 public class CollableDemo { 10 public static void main(String[] args) throws ExecutionException, InterruptedException { 11 FutureTask<Integer> futureTask = new FutureTask<>(new CallableThread()); 12 Thread t1 = new Thread(futureTask,"CallableThread"); 13 t1.start(); 14 System.out.println(futureTask.get());//2048 15 } 16 }
Runnable接口和Callable接口的實現類,都可以被ThreadPoolExecutor或Scheduled-ThreadPoolExecutor執行。它們之間的區別是Runnable不會返回結果,而Callable可以返回結果。除了可以自己創建實現Callable接口的對象外,還可以使用工廠類Executors來把一個Runnable包裝成一個Callable。
下面是Executors提供的,把一個Runnable包裝成一個Callable的API。
public static Callable<Object> callable(Runnable task) // 假設返回對象Callable1
下面是Executors提供的,把一個Runnable和一個待返回的結果包裝成一個Callable的API。
public static <T> Callable<T> callable(Runnable task, T result) // 假設返回對象Callable