一.Java創建線程的三種方式 Java中創建線程主要有三種方式: 1.繼承Thread類 2.實現Runnable介面 3.使用Callable和Future 1.繼承Thead類創建線程 (1)繼承Thread類並重寫run方法 (2)創建線程對象 (3)調用該線程對象的start()方法來啟動 ...
一.Java創建線程的三種方式
Java中創建線程主要有三種方式:
1.繼承Thread類
2.實現Runnable介面
3.使用Callable和Future
1.繼承Thead類創建線程
(1)繼承Thread類並重寫run方法
(2)創建線程對象
(3)調用該線程對象的start()方法來啟動線程
public class CreateThreadTest {
public static void main(String[] args) {
new ThreadTest().start();
new ThreadTest().start();
}
}
class ThreadTest extends Thread{
private int i = 0;
@Override
public void run() {
for (; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " is running: " + i);
}
}
}
2.實現Runnable介面創建線程
(1)定義一個類實現Runnable介面,並重寫該介面的run()方法
(2)創建 Runnable實現類的對象,作為創建Thread對象的target參數,此Thread對象才是真正的線程對象
(3)調用線程對象的start()方法來啟動線程
public class CreateThreadTest {
public static void main(String[] args) {
RunnableTest runnableTest = new RunnableTest();
new Thread(runnableTest, "線程1").start();
new Thread(runnableTest, "線程2").start();
}
}
class RunnableTest implements Runnable{
private int i = 0;
@Override
public void run() {
for (; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " is running: " + i);
}
}
}
3.使用Callable和Future創建線程
和Runnable介面不一樣,Callable介面提供了一個call()方法作為線程執行體,call()方法比run()方法功能要強大:call()方法可以有返回值,可以聲明拋出異常。
public interface Callable<V> {
V call() throws Exception;
}
Java5提供了Future介面來接收Callable介面中call()方法的返回值。 Callable介面是 Java5 新增的介面,不是Runnable介面的子介面,所以Callable對象不能直接作為Thread對象的target。針對這個問題,引入了RunnableFuture介面,RunnableFuture介面是Runnable介面和Future介面的子介面,可以作為Thread對象的target 。同時,Java5提供了一個RunnableFuture介面的實現類:FutureTask ,FutureTask可以作為Thread對象的target。
介紹了相關概念之後,使用Callable和Future創建線程的步驟如下:(1)定義一個類實現Callable介面,並重寫call()方法,該call()方法將作為線程執行體,並且有返回值
(2)創建Callable實現類的實例,使用FutureTask類來包裝Callable對象
(3)使用FutureTask對象作為Thread對象的target創建並啟動線程
(4)調用FutureTask對象的get()方法來獲得子線程執行結束後的返回值
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CreateThreadTest {
public static void main(String[] args) {
CallableTest callableTest = new CallableTest();
FutureTask<Integer> futureTask = new FutureTask<>(callableTest);
new Thread(futureTask).start();
try {
System.out.println("子線程的返回值: " + futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class CallableTest implements Callable{
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i < 101; i++) {
sum += i;
}
System.out.println(Thread.currentThread().getName() + " is running: " + sum);
return sum;
}
}
二.創建線程的三種方式的對比
1.實現Runnable/Callable介面相比繼承Thread類的優勢
(1)適合多個線程進行資源共用
(2)可以避免java中單繼承的限制
(3)增加程式的健壯性,代碼和數據獨立
(4)線程池只能放入Runable或Callable介面實現類,不能直接放入繼承Thread的類
2.Callable和Runnable的區別
(1) Callable重寫的是call()方法,Runnable重寫的方法是run()方法
(2) call()方法執行後可以有返回值,run()方法沒有返回值
(3) call()方法可以拋出異常,run()方法不可以
(4) 運行Callable任務可以拿到一個Future對象,表示非同步計算的結果 。通過Future對象可以瞭解任務執行情況,可取消任務的執行,還可獲取執行結果
感謝你讀完了這篇文章
我是小架,我們
中秋節後見,祝大家中秋快樂!