實現多線程
java實現多線程的方法有三種,分別是繼承thread類,實現runnable接口,實現callable接口(call方法有返回值)
/**
* 繼承Thread
*/
public class MyThread extends Thread{
int a = 0;
@Override
public void run() {
//線程的核心實現
synchronized (this){
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( ++a );
}
}
}
class MyThreadTest{
public static void main(String[] args) {
//實例三個線程
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
MyThread myThread3 = new MyThread();
//啟動三個線程
myThread1.start();
myThread2.start();
myThread3.start();
}
}
輸出結果:

/**
* 實現Runnable接口
*/
public class MyRunnable implements Runnable {
int a = 0;
@Override
public void run() {
//線程核心處理方法
System.out.println(++a);
}
}
class MyRunnableTest {
public static void main(String[] args) {
//實例話MyRunnable
Runnable runnable = new MyRunnable();
//通過runnable實例化三個線程
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
Thread thread3 = new Thread(runnable);
//啟動三個線程
thread1.start();
thread2.start();
thread3.start();
// 輸出的結果為1 2 3 ,輸出的順序可能不同
}
}
輸出結果:

/**
*
* 實現Callable接口
*/
public class MyCallable implements Callable<String> {
int a = 0;
@Override
public String call() throws Exception {
++a;
System.out.println(Thread.currentThread().getName() + ",a=" + a);
return String.valueOf(a);
}
}
class TestCallable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable callable = new MyCallable();
FutureTask<String> task = new FutureTask<String>(callable);
Thread thread1 = new Thread(task,"線程一");
Thread thread2 = new Thread(task,"線程二");
Thread thread3 = new Thread(task,"線程三");
thread1.start();
thread2.start();
thread3.start();
// 取得返回值
System.out.println(task.get());
}
}
輸出結果:

Thread、Runnable、Callable接口實現多線程的區別
觀察以上三種實現方式和輸出的結果可得
1.繼承Thread方式,每次new Thread都是獨立的,資源不共享,而Runnable資源共享;
2.實現Callable接口方式,只能運行一次FutureTask
Thread類與Runnable接口實現多線程的區別
1.Thread類是Runnable接口的子類,使用runnable接口實現多線程可以避免單繼承局限;
2.Runnable接口實現的多線程可以比Thread類實現的多線程更加清楚的描述數據共享的概念。
如何理解:
因為一個線程只能啟動一次,通過Thread實現線程時,線程和線程所要執行的任務是捆綁在一起的。也就使得一個任務只能啟動一個線程,不同的線程執行的任務是不相同的,所以沒有必要,也不能讓兩個線程共享彼此任務中的資源。
通過Runnable方式實現的線程,實際是開辟一個線程,將任務傳遞進去,由此線程執行。可以實例化多個 Thread對象,將同一任務傳遞進去,也就是一個任務可以啟動多個線程來執行它。這些線程執行的是同一個任務,所以他們的資源是共享。
Calleble接口
1.最大的特點就是可以通過FutureTask獲得線程核心處理方法的返回值(run方法是無返回值的
2.get方法會阻塞主線程來等待任務完成。FutureTask非常適合用於耗時的計算,主線程可以在完成自己的任務后,再去獲取結果
3. FutureTask被多次調用,依然只會執行一次Runnable任務
