1.繼承於Thread類,重寫run()方法;
2.實現Runable接口,實現裏面的run()方法;
前兩種不用多說
3.使用 FutureTask 實現有返回結果的線程,可以返回線程執行結果
public class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<Double> task = new FutureTask(new MyCallable());
//創建一個線程,異步計算結果
Thread thread = new Thread(task);
thread.start();
//主線程繼續工作
Thread.sleep(1000);
System.out.println("主線程等待計算結果...");
//當需要用到異步計算的結果時,阻塞獲取這個結果
Double d = task.get();
System.out.println("計算結果是:"+d);
//用同一個 FutureTask 再起一個線程
Thread thread2 = new Thread(task);
thread2.start();
}
}
class MyCallable implements Callable<Double>{
@Override
public Double call() {
double d = 0;
try {
System.out.println("異步計算開始.......");
d = Math.random()*10;
d += 1000;
Thread.sleep(2000);
System.out.println("異步計算結束.......");
} catch (InterruptedException e) {
e.printStackTrace();
}
return d;
}
}
4.使用ExecutorService、Executors 線程池。
public class MyTest {
public static void main(String[] args) {
//創建一個只有一個線程的線程池
ExecutorService executorService = Executors.newFixedThreadPool(3);
//創建任務,並提交任務到線程池中
executorService.execute(new MyRunable("任務1"));
executorService.execute(new MyRunable("任務2"));
executorService.execute(new MyRunable("任務3"));
}
}
class MyRunable implements Runnable{
private String taskName;
public MyRunable(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
System.out.println("線程池完成任務:"+Thread.currentThread().getName()+taskName);
}
}
二、關於run()方法的思考
看看下面這種情況:線程類Thread 接收了外部任務,同時又用匿名內部類的方式重寫了內部的run()方法,這樣豈不是有兩個任務,那麼究竟會執行那個任務呢?還是兩個任務一起執行呢?
public class TestNeibu{
public static void main(String[] args) {
Thread thread = new Thread(new MyTask()){
@Override
public void run() {//重寫Thread類的run方法
System.out.println("Thread 類的run方法");
}
};
//線程啓動
thread.start();
}
}
class MyTask implements Runnable{
//重寫run方法
@Override
public void run() {
//任務內容....
System.out.println("這是Runnable的run方法");
}
}
運行結果如下:
Thread 類的run方法
Thread類的run方法在沒有重寫的情況下,是判斷一下是否有Runnable 對象傳進來,如果有,那麼就調用Runnable 對象裏的run方法;否則,就什麼都不幹,線程結束。所以,針對上面的例子,一旦你繼承重寫了Thread類的run()方法,而你又想可以接收Runable類的對象,那麼就要加上super.run(),執行沒有重寫時的run方法,改造如下
Thread thread = new Thread(new MyTask()){
@Override
public void run() {//重寫Thread類的run方法
//調用父類Thread的run方法,即沒有重寫時的run方法
super.run();
System.out.println("Thread 類的run方法");
}
};
thread.start();