1. 程式人生 > >多執行緒學習(4):三種實現Java多執行緒的方法:Thread、Callable和Runable 的比較與區別

多執行緒學習(4):三種實現Java多執行緒的方法:Thread、Callable和Runable 的比較與區別

2018年10月03日

目錄

前言

前言

JVM允許應用程式併發執行多執行緒:最常用的是兩個方法:(1)基礎Thread類,重寫run()方法;(2)或實現Runnable 介面,實現介面的run()方法;(3)另外一種方法是:實現callable 介面,重寫call()方法。

1、繼承Thread類

啟動執行緒的唯一方法就是通過Thread類的start()方法。start()是native方法,呼叫可以使得該執行緒變為可允許態(Runnable),而什麼時候執行多執行緒程式碼,則是由作業系統決定。

package test3ThreadWays;

public class testThread {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread myThread = new MyThread();
		myThread.start(); //開啟了執行緒,搶佔cpu資源
	}

}

class MyThread extends Thread{
	public void run(){
		System.out.println("Thread body 。。"); //任務:執行緒的函式體
	}	
}

console:

Thread body 。。

2、實現Runnable介面,實現run()方法

使用Runnable介面,需要建立Thread物件,用於實現Runnable介面的物件作為引數例項化該Thread物件。

package test3ThreadWays;

public class testRunnable {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		myRunnable myThread = new myRunnable(); //任務
		Thread thread = new Thread(myThread); //執行緒
		thread.start();
	}

}

class myRunnable implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("Runnable body..");
	}
	
}

console:

Runnable body..

3、實現Callable介面,重寫call()方法

區別:1)任務結束後提供一個返回值,Runnable的run()無法提供該功能;

2)call()可以丟擲異常,Runnable的run()無法丟擲異常;

3)Callable可以拿到Future物件,表示非同步計算的結果,它提供了get()方法【檢查計算是否完成】,獲取結果;但是當前執行緒會阻塞;

package test3ThreadWays;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class testCallable {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ExecutorService threadPool = Executors.newSingleThreadExecutor();
		
		//啟動執行緒
		Future<String> future = threadPool.submit(new myCallable());
		
		try{
			System.out.println("waiting the thread to finish,,,");
			System.out.println("獲取監聽執行緒返回值: "+future.get()); //使用Future監視目標執行緒呼叫call()方法的情況,當前的執行緒會一直阻塞,直到call()方法結束返回結果。
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}

}
/**
 * callable 比 runnable 強大的地方是:可以返回結果值
 * @return String
 * @others:介面是 Executor 框架的功能類;
 * */
class myCallable implements Callable<String>{

	@Override
	public String call() throws Exception {
		System.out.println("callable body...");
		Thread.sleep(2000);
		return "Hello World!!";
	}
	
}

console:

waiting the thread to finish,,, callable body... 獲取監聽執行緒返回值: Hello World!!