一 創建線程的三種方式
1、Thread方式
/**
* 多線程創建的方式1
* 1. 創建Thread的子類
* 2. 重寫run方法 [業務執行體-邏輯主要存在的地方]
* 3. 創建子類的示例.start啓動
*/
public class ThreadCreateMethodOne extends Thread {
/**
* 繼承Thread方式定義的線程,要將變量定義成static 類變量資源才能被共享
*/
public static int i = 100;
public static Object obj = new Object();
@Override
public void run() {
while (i > 0) {
synchronized (obj) {
try {
i--;
System.out.println(this.getName() + (i > 0 ? (": 餘票 " + i + " 張") : (": 已售完")));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2、Runnable 方式
/**
* 線程創建的方式2
* 1. 實現Runnable
* 2. 重寫run方法
* 3. 創建實例
* 4. 將實例作爲參數傳遞給new Thread(Runnable runnable, String name)
* 5. start 啓動
*
*/
public class ThreadCreateMethodSecond implements Runnable {
int i =100;
Object obj = new Object();
@Override
public void run() {
while (i > 0) {
synchronized (obj) {
try {
i--;
System.out.println(Thread.currentThread().getName() + (i > 0 ? (": 餘票 " + i + " 張") : (": 已售完")));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final ThreadCreateMethodSecond th1 = new ThreadCreateMethodSecond();
new Thread(th1,"窗口1").start();
new Thread(th1,"窗口2").start();
}
}
3、Callable 方式
/**
* 線程創建的方式3
* 1. 實現Callable
* 2. 重寫call方法 有返回值
* 3. 創建Callable 子類的實例
* 4. 將Callable 子類的實例傳遞給 new FutureTask(Callable)
* 5. 將FutureTask 實例作爲參數傳給 new Thread(FutureTask task,String name)
* 6. start 啓動
*/
public class ThreadCreateMethodThree implements Callable<Integer> {
int i =100;
@Override
public Integer call() {
while (i > 0) {
try {
i--;
System.out.println(Thread.currentThread().getName() + (i > 0 ? (": 餘票 " + i + " 張") : (": 已售完")));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return i;
}
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
final FutureTask<Integer> task = new FutureTask<>(new ThreadCreateMethodThree());
new Thread(task,"窗口1").start();
System.out.println("返回值---------------------"+task.get());
}
}
二、三種線程對比
上述3種方式都可以實現多線程,存在即合理;
-
Runnable 和 callable方式:[推薦]
- 優點
- 線程類在實現Runnable/callable的前提下還可以去繼承其他類.更加面向對象
- Callable 是JDK1.5版本出來的.JDK1.8加強[Lamdba/函數式接口],Runbale JDK1.8也支持函數式編程
- Runable和Callable更加適合處理共享資源的情況
- 劣勢
- 編程稍稍麻煩一下.而且獲取當前線程需要使用Thread類的靜態方法currentThread()方法
- 優點
-
Thread 方式
- 優點
- 編程簡單.可以直接獲取當前線程
- 劣勢
- java單繼承.無法繼承其他類.有侷限性
- 優點
本文參考 <<瘋狂java第三版>> 16章節