一、線程實現的三種方式
- 繼承Thread類
- 實現Runnable接口
- 實現Callable接口,需要實現的是call方法
二、代碼的簡單實現
package cn.xdf.threadpool;
public class RunnableDemo {
//1.繼承 Thread方式的線程
public static class TestThreadDemo extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--繼承 Thread方式--在運行!");
}
}
//2.1 實現runnable接口方式的線程
public static class TestRunnableDemo implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--實現runnable接口方式--在運行!");
}
}
public static void main(String[] args) {
//調用1. 繼承 Thread方式
TestThreadDemo tt1 = new TestThreadDemo();
TestThreadDemo tt2 = new TestThreadDemo();
tt1.start();//Thread-0--繼承 Thread方式--在運行!
tt2.start();//Thread-1--繼承 Thread方式--在運行!
//調用2.1 實現runnable接口方式 的
TestRunnableDemo t1 = new TestRunnableDemo();
TestRunnableDemo t2 = new TestRunnableDemo();
new Thread(t1).start();//Thread-2--實現runnable接口方式--在運行!
new Thread(t2).start();//Thread-3--實現runnable接口方式--在運行!
//調用2.2 new Runnable對象方式
Runnable runnable = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"--new Runnable對象方式--在運行!");
}
};
new Thread(runnable).start();//Thread-4--new Runnable對象方式--在運行!
//這5個線程的調用順序不一定
}
}
package cn.xdf.threadpool;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//3.2 new Callable方式的實現線程
Callable<String> callable = new Callable<String>(){//Callable方式的線程
@Override
public String call() throws Exception {
Random random = new Random();
return "返回值爲:"+random.nextInt(200);//根據FutureTask 可以獲取這個返回值!!!
}
};
FutureTask<String> futureTask = new FutureTask<>(callable);//根據FutureTask 獲取返回值
new Thread(futureTask).start();//開啓一個線程
String result = futureTask.get();//需要拋異常 //根據FutureTask 獲取返回值
System.out.println("result:"+result);//result:返回值爲:140
//3.1 實現Callable接口
TestCallableDemo cd1 = new TestCallableDemo();
FutureTask<String> ft = new FutureTask<>(cd1);//根據FutureTask 獲取返回值
new Thread(ft).start();//開啓一個線程
String rs = ft.get();//需要拋異常 //根據FutureTask 獲取返回值
System.out.println("rs:"+rs);//rs:Thread-1--實現Callable接口方式的線程--在運行!
}
//3.1 實現Callable接口
public static class TestCallableDemo implements Callable{
@Override
public String call() throws Exception {
String result = Thread.currentThread().getName()+"--實現Callable接口方式的線程--在運行!";
return result;
}
}
}
三、總結:
1.Runnable接口的話,可以避免單繼承的侷限性,具有較強的健壯性。
2.Runnable可以實現資源的共享,同時處理同一資源。
3.Thread類的線程間都是獨立運行的,資源不共享。
4.繼承Thread類不再被其他類繼承(java不存在多繼承)
5.Callable是一個接口,Callable使用call( )方法,可以返回值;Runnable使用run( )方法,沒有返回值。
6.call() 可以拋出受檢查的異常,比如ClassNotFoundException, 而run()不能拋出受檢查的異常