多線程編程之Runnable與Callable區別
阿新 • • 發佈:2018-12-06
cond 的區別 stat result tel 基本上 ace 哈哈 separate Runnable
@FunctionalInterface public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object‘s * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }
Callable
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
相同點:
1.都是接口,都能夠實現多線程編程,都需要Thread.start()來啟動線程。
不同點:
1.Callable接口支持返回執行結果,此時需要調用FutureTask.get()方法實現,此方法會阻塞主線程直到獲取‘將來’結果;當不調用此方法時,主線程不會阻塞!
Callable使用
/** * CallableImpl 簡要描述 * <p> TODO:描述該類職責 </p> * * @author ckmike * @version 1.0 * @date 18-12-6 下午8:53 * @copyright ckmike **/ public class CallableImpl implements Callable<String> { private String accept; public CallableImpl(String accept) { this.accept = accept; } @Override public String call() throws Exception { // 休眠 TimeUnit.SECONDS.sleep(3); return this.accept; } public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<String> callable = new CallableImpl("my callable test!"); FutureTask<String> task = new FutureTask<>(callable); long beginTime = System.currentTimeMillis(); // 創建線程 new Thread(task).start(); // 調用get()阻塞主線程,反之,線程不會阻塞 String result = task.get(); long endTime = System.currentTimeMillis(); System.out.println("hello : " + result); System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!"); } }
Runnable使用
/**
* RunnableImpl 簡要描述
* <p> TODO:描述該類職責 </p>
*
* @author ckmike
* @version 1.0
* @date 18-12-6 下午9:03
* @copyright ckmike
**/
public class RunnableImpl implements Runnable {
public RunnableImpl(String accept) {
this.accept = accept;
}
private String accept;
@Override
public void run() {
// 線程阻塞 1 秒,此時有異常產生,只能在方法內部消化,無法上拋
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 最終處理結果無法返回
System.out.println("hello : " + this.accept);
}
public static void main(String[] args) {
Runnable runnable = new RunnableImpl("my runable test!");
long beginTime = System.currentTimeMillis();
new Thread(runnable).start();
long endTime = System.currentTimeMillis();
System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!");
}
}
寫這篇文章的原因是:面試時問道Runnable與Callable的區別,平時也就用Runnable比較多,基本上沒有用過Callable,所以就掛了,哈哈哈,也總結給有需要的朋友。有知道Callable接口的使用場景嗎?有的話可以留意分享給我嗎?謝謝了!
多線程編程之Runnable與Callable區別