1,繼承Thread類
繼承Thread類,重寫run方法(不推薦,因為java的單繼承局限性)
1 public class ExtendThread extends Thread { 2 3 /* 4 * 創建步驟如下: 5 * 1,定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務。因此把run方法稱為線程執行體。 6 * 2,創建Thread子類了的實例,即創建線程對象。本實例中是new一個ExtendThread,即可創建線程對象,也就是開啟了一個線程 7 * 3,調用線程對象的start()方法來啟動該線程。 8 * 9 * 調用示例: 10 * //循環10次即開啟10個線程 11 * for (int i = 0; i < 10; i++) { 12 * ExtendThread extendThread = new ExtendThread(); 13 * extendThread.start(); 14 * } 15 * */ 16 17 /** 18 * 重寫Thread類的run(),這個方法稱為線程執行體 19 * */ 20 @Override 21 public void run() { 22 doSomething(); 23 } 24 25 /** 26 * 需要處理的任務 27 * */ 28 public void doSomething(){ 29 for (int i = 0; i < 10; i++) { 30 System.out.println(Thread.currentThread().getName() + "執行" + i); 31 } 32 } 33 }
2,實現Runnable接口
方式一:直接實現Runnable接口(避免單繼承的局限性,方便共享資源,推薦使用)
1 public class RunnableImpl implements Runnable { 2 3 /* 4 * 創建步驟如下: 5 * 1,定義Runnable接口的實現類,並且實現run方法,這個方法同樣是線程執行體 6 * 2,創建Runnable實現類的實例,並以此實例對象作為Thread的target來創建Thread類,這個新創建的Thread對象才是真正的線程對象,即開啟了新的線程 7 * 3,調用線程對象的start()方法來開啟該線程 8 * 9 * 調用示例: 10 * //開啟10個線程 11 * for (int i = 0; i < 10; i++) { 12 * Thread thread = new Thread(new RunnableImpl()); 13 * thread.start(); 14 * } 15 * */ 16 17 /** 18 * 實現Runnable接口的run方法,這個方法稱為線程執行體 19 * */ 20 @Override 21 public void run() { 22 doSomething(); 23 } 24 25 /** 26 * 需要處理的任務 27 * */ 28 private void doSomething(){ 29 for (int i = 0; i < 10; i++) { 30 System.out.println(Thread.currentThread().getName() + "執行" + i); 31 } 32 } 33 }
方式二:匿名內部類
1 public class Anonymous { 2 3 /* 4 * 創建步驟如下: 5 * 匿名內部類本質上也是一個類實現了Runnable接口,重寫了run方法,只不過這個類沒有名字,直接作為參數傳入Thread類 6 * 7 * 調用示例: 8 * //開啟10個線程 9 * for (int i = 0; i < 10; i++) { 10 * Anonymous anonymous =new Anonymous(); 11 * anonymous.myRun(); 12 * } 13 * 14 * */ 15 16 public void myRun(){ 17 new Thread(new Runnable() { 18 @Override 19 public void run() { 20 doSomething(); 21 } 22 }).start(); 23 } 24 25 /** 26 * 需要處理的任務 27 * */ 28 private void doSomething(){ 29 for (int i = 0; i < 10; i++) { 30 System.out.println(Thread.currentThread().getName() + "執行" + i); 31 } 32 } 33 }
3,實現Callable接口
1 public class CallableImpl implements Callable<String> { 2 3 /* 4 * 創建步驟如下: 5 * 1,定義實現Callable<V>接口的實現類,實現call方法,這個方法是線程執行體 6 * 2,創建Callable<V>實現類的實例,借助FutureTask得到線程執行的返回值 7 * 3,將FutureTask的實例,作為Thread的target來創建Thread類 8 * 4,調用start方法,開啟線程 9 * 10 * 調用示例: 11 * Callable<String> tc = new CallableImpl(); 12 * FutureTask<String> task = new FutureTask<>(tc); 13 * new Thread(task).start(); 14 * try { 15 * System.out.println(task.get()); 16 * } catch (InterruptedException | ExecutionException e) { 17 * e.printStackTrace(); 18 * } 19 * 20 * 說明: 21 * 1.與使用Runnable相比, Callable功能更強大些 22 * 2.實現的call()方法相比run()方法,可以返回值 23 * 3.方法可以拋出異常 24 * 4.支持泛型的返回值 25 * 5.需要借助FutureTask類,比如獲取返回結果 26 * Future接口可以對具體Runnable、Callable任務的執行結果進行取消、查詢是否完成、獲取結果等。 27 * FutureTask是Futrue接口的唯一的實現類 28 * FutureTask 同時實現了Runnable, Future接口。它既可以作為Runnable被線程執行,又可以作為Future得到Callable的返回值 29 * 30 * */ 31 32 private int ticket = 5; 33 34 @Override 35 public String call() throws Exception { 36 for (int i = 0; i < 10; i++) { 37 System.out.println(doSomething()); 38 } 39 40 return "出票任務完成"; 41 } 42 43 public String doSomething() { 44 String result = ""; 45 if (this.ticket > 0) { 46 result = "出票成功,ticket=" + this.ticket--; 47 } else { 48 result = "出票失敗,ticket=" + this.ticket; 49 } 50 return result; 51 } 52 }
4,創建線程池
1 public class ThreadPool implements Runnable { 2 3 /* 4 * 創建步驟如下: 5 * 1,定義Runnable接口的實現類,或者定義(繼承Runnable接口的類)的實現類,並且實現run方法,這個方法是線程執行體 6 * 2,創建一個自定義線程個數的線程池 7 * 3,實例化Runnable接口的實現類 8 * 4,將3步的實例,作為線程池實例的execute方法的command參數,開啟線程 9 * 5,關閉線程池 10 * 11 * 調用示例: 12 * ExecutorService pool = Executors.newFixedThreadPool(2); 13 * ThreadPool threadPool = new ThreadPool("AA"); 14 * ThreadPool threadPoo2 = new ThreadPool("BB"); 15 * pool.execute(threadPool); 16 * pool.execute(threadPoo2); 17 * pool.shutdown(); 18 * 19 * 說明: 20 * 示例中創建的是2個線程的線程池 21 * execute方法是開啟線程方法,實參要求是實現Runnable的類。所以,繼承Thread類的子類也可以以線程池的方式開啟線程 22 * 23 * */ 24 25 String name; 26 public ThreadPool(String name) { 27 this.name = name; 28 } 29 30 @Override 31 public void run() { 32 doSomething(); 33 } 34 35 /** 36 * 需要處理的任務 37 * */ 38 private void doSomething() { 39 for (int i = 0; i < 10; i++) { 40 System.out.println(Thread.currentThread().getName() + "執行" + i + ",name=" + this.name); 41 } 42 } 43 }