文章目錄
1、多線程主要的實現方式:
一種是繼承Thread類
一種實現Runnable接口
2、繼承Thread類和實現Runnable接口的區別:
-
由於Java是單繼承方式,如果線程類已經繼承了其它類,就不能使用繼承Thread類的方式,但是可以轉而使用實現Runnable接口的方式
-
Thread類的run方法不能共享,比如說線程A不能把線程B的run方法當成是自己的執行單元,而使用Runnable則可以很容易實現,因爲同一個Runnable可以構造多個實例,通俗的說可以理解Runnable相當於是Thread的task
-
從職責上來講,Thread類主要負責線程本身相關職責與控制,而Runnable主要負責線程邏輯的執行單元
3、線程實現的所有方式
- 繼承Thread類
- 實現Runnable接口
- 實現Callable接口,並通過FutureTask進行包裝
- 使用匿名內部類
- 使用Lambda表達式
- 使用線程池
- 使用定時器
3.1、繼承Thread類
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println("繼承Thread方式");
}
public static void main(String[] args) {
Thread1 thread = new Thread1();
thread.start();
}
}
3.2、實現Runnable接口
public class Thread2 implements Runnable {
@Override
public void run() {
System.out.println("實現Runnable接口方式");
}
public static void main(String[] args) {
Runnable runnable = new Thread2();
Thread thread2 = new Thread(runnable);
thread2.start();
}
}
3.3、實現Callable接口,並通過FutureTask包裝
public class Thread3 implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(5000);
return "實現Callable方式,並通過FutureTask包裝,有返回值";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
Thread3 thread3 = new Thread3();
FutureTask futureTask = new FutureTask(thread3);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("線程已經啓動");
// 同步方式獲取返回結果
String result = (String) futureTask.get();
System.out.println(result);
}
}
3.4、匿名內部類
匿名內部類也有多種變體,上述三種方式都可以使用匿名內部類來隱式實例化。
public class Demo{
public static void main(String[] args) throws Exception {
//方式一:Thread匿名內部類
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
}
}.start();
//方式二:Runnable匿名內部類
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
...
}
}
匿名內部類的優點在於使用方便,不用額外定義類,缺點就是代碼可讀性差。
3.5、Lambda表達式
public class Demo{
public static void main(String[] args) throws Exception {
new Thread(() -> System.out.println("running") ).start() ;
...
}
}
Runnable被@FunctionalInterface註解所修飾,並且接口中僅有一個方法
3.6、線程池
public class DemoThreadTask implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("running");
}
public static void main(String[] args) {
DemoThreadTask task = new DemoThreadTask();
ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(task);
}
}
3.7、定時器
public class DemoTimmerTask {
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
timer.scheduleAtFixedRate((new TimerTask() {
@Override
public void run() {
System.out.println("任務執行");
}
}), 2000, 1000);
}
}
TimerTask的實現了Runnable接口,Timer內部有個TimerThread繼承自Thread。