Java 中有 4 種常見的創建線程的方式。
一、重寫 Thread 類的 run() 方法。
表現形式有兩種:1)new Thread 對象匿名重寫 run() 方法
package constxiong.concurrency.a006; /** * new Thread 對象匿名重寫 run() 方法,啟動線程 * @author ConstXiong */ public class TestNewThread { public static void main(String[] args) { //創建線程 t, 重寫 run() 方法 new Thread("t") { @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println("thread t > " + i); } } }.start(); } }
執行結果
thread t > 0
thread t > 1
thread t > 2
2)繼承 Thread 對象,重寫 run() 方法
package constxiong.concurrency.a006; /** * 繼承 Thread 類,重寫 run() 方法 * @author ConstXiong */ public class TestExtendsThread { public static void main(String[] args) { new ThreadExt().start(); } } //ThreadExt 繼承 Thread,重寫 run() 方法 class ThreadExt extends Thread { @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println("thread t > " + i); } } }
執行結果
thread t > 0
thread t > 1
thread t > 2
二、實現 Runnable 接口,重寫 run() 方法。
表現形式有兩種:1)new Runnable 對象,匿名重寫 run() 方法
package constxiong.concurrency.a006; /** * new Runnalbe 對象匿名重寫 run() 方法,啟動線程 * @author ConstXiong */ public class TestNewRunnable { public static void main(String[] args) { newRunnable(); } public static void newRunnable() { //創建線程 t1, 重寫 run() 方法 new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println("thread t1 > " + i); try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "t1").start(); //創建線程 t2, lambda 表達式設置線程的執行代碼 //JDK 1.8 開始支持 lambda 表達式 new Thread(() -> { for (int i = 0; i < 3; i++) { System.out.println("thread t2 > " + i); try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t2").start(); } }
執行結果
thread t1 > 0
thread t2 > 0
thread t1 > 1
thread t2 > 1
thread t1 > 2
thread t2 > 2
2)實現 Runnable 接口,重寫 run() 方法
package constxiong.concurrency.a006; /** * 實現 Runnable 接口,重寫 run() 方法 * @author ConstXiong */ public class TestImplRunnable { public static void main(String[] args) { new Thread(new RunnableImpl()).start(); } } ///RunnableImpl 實現 Runnalbe 接口,重寫 run() 方法 class RunnableImpl implements Runnable { @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println("thread t > " + i); } } }
執行結果
thread t > 0
thread t > 1
thread t > 2
三、實現 Callable 接口,使用 FutureTask 類創建線程
package constxiong.concurrency.a006; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 實現 Callable 接口,使用 FutureTask 類創建線程 * @author ConstXiong */ public class TestCreateThreadByFutureTask { public static void main(String[] args) throws InterruptedException, ExecutionException { //通過構造 FutureTask(Callable callable) 構造函數,創建 FutureTask,匿名實現接口 Callable 接口 FutureTask<String> ft = new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { return "ConstXiong"; } }); //Lambda 方式實現 // FutureTask<String> ft = new FutureTask<String>(() -> "ConstXiong"); new Thread(ft).start(); System.out.println("執行結果:" + ft.get()); } }
執行結果
執行結果:ConstXiong
四、使用線程池創建、啟動線程
package constxiong.concurrency.a006; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 線程池的方式啟動線程 * @author ConstXiong */ public class TestCreateThreadByThreadPool { public static void main(String[] args) { // 使用工具類 Executors 創建單線程線程池 ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); //提交執行任務 singleThreadExecutor.submit(() -> {System.out.println("單線程線程池執行任務");}); //關閉線程池 singleThreadExecutor.shutdown(); } }
執行結果
單線程線程池執行任務
PS:這邊只是簡單的使用示例,至於 Runnable 接口和 Callable 接口的區別、線程池的使用,后面詳細探索。
來一道刷了進BAT的面試題?