Java 的Runnable和Callable的区别
Runnable和Callable的區別是,
(1)Callable規定的方法是call(),Runnable規定的方法是run().
(2)Callable的任務執行后可返回值,而Runnable的任務是不能返回值得
(3)call方法可以拋出異常,run方法不可以
(4)運行Callable任務可以拿到一個Future對象,表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,并檢索計算的結果。通過Future對象可以了解任務執行情況,可取消任務的執行,還可獲取執行結果。
1.1使用Runnble接口?創建線程
public class RunnableTest implements Runnable {@Overridepublic void run() {System.out.println("this thread name is:"+Thread.currentThread().getName());}public static void main(String[] args) {System.out.println(Thread.currentThread().getName());RunnableTest r = new RunnableTest();Thread t = new Thread(r);t.start();} }或者使用匿名類實現:
Thread thread =new Thread(new Runnable() {public void run() {// TODO Auto-generated method stubSystem.out.println("匿名類實現線程");}使用1.2 使用 Executors 創建線程
package com.asiainfo.proxydemo;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class ThreadExecutorService {//設置線程的數量private static int POOL_NUM=10;/*** @param args*/public static void main(String[] args) { // ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3); // ExecutorService newFixedThreadPool = Executors.newCachedThreadPool(); // ExecutorService newFixedThreadPool = Executors.newScheduledThreadPool(3); // ExecutorService newFixedThreadPool = Executors.newSingleThreadExecutor();ExecutorService newFixedThreadPool = Executors.newSingleThreadScheduledExecutor();for (int i = 0; i < POOL_NUM; i++) {RunnableImpl runnableImpl = new RunnableImpl("thread--"+i);newFixedThreadPool.execute(runnableImpl);}newFixedThreadPool.shutdown();}} class RunnableImpl implements Runnable{private String name;public RunnableImpl(String name) {super();// TODO Auto-generated constructor stubthis.name=name;}public void run() {// TODO Auto-generated method stubSystem.out.println("hello ExecutorService"+name);}}2.1 使用Callable 創建線程
package com.asiainfo.proxydemo;import java.util.concurrent.Callable; import java.util.concurrent.FutureTask;public class ThreadCallable {/*** @param args*/ public static void main(String[] args) {Tickets<java.lang.Object> tickets = new Tickets<Object>();FutureTask<java.lang.Object> futureTask = new FutureTask<Object>(tickets);Thread thread = new Thread(futureTask);System.out.println(Thread.currentThread().getName());thread.start(); } } class Tickets<Object> implements Callable<Object>{/* (non-Javadoc)* @see java.util.concurrent.Callable#call()*/public Object call() throws Exception {// TODO Auto-generated method stubSystem.out.println(Thread.currentThread().getName()+"通過實現Callable接口通過FutureTask包裝器來實現線程");return null;}}? ? ?2.2 使用 Executors 結合Callable 創建多線程
? ? ? 在Java5之 后,任務分兩類:一類是實現了Runnable接口的類,一類是實現了Callable接口的類。兩者都可以被ExecutorService執行,但是 Runnable任務沒有返回值,而Callable任務有返回值。并且Callable的call()方法只能通過ExecutorService的 submit(Callable<T> task) 方法來執行,并且返回一個 <T> Future<T>,是表示任務等待完成的 Future.
public interface Callable<V>返回結果并且可能拋出異常的任務。實現者定義了一個不帶任何參數的叫做 call 的方法。
Callable 接口類似于 Runnable,兩者都是為那些其實例可能被另一個線程執行的類設計的。但是 Runnable 不會返回結果,并且無法拋出經過檢查的異常。
Executors 類包含一些從其他普通形式轉換成 Callable 類的實用方法。
Callable中的call()方法類似Runnable的run()方法,就是前者有返回值,后者沒有。
當將一個Callable的對象傳遞給ExecutorService的submit方法,則該call方法自動在一個線程上執行,并且會返回執行結果Future對象。
同樣,將Runnable的對象傳遞給ExecutorService的submit方法,則該run方法自動在一個線程上執行,并且會返回執行結果Future對象,但是在該Future對象上調用get方法,將返回null.
package com.asiainfo.proxydemo;import java.util.ArrayList; import java.util.List; import java.util.concurrent.*;public class ThreadCallableDemo2 {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();List<Future<String>> resultList = new ArrayList<Future<String>>();// 創建10個任務并執行for (int i = 0; i < 10; i++) {// 使用ExecutorService執行Callable類型的任務,并將結果保存在future變量中Future<String> future = executorService.submit(new TaskWithResult(i));// 將任務執行結果存儲到List中resultList.add(future);}// 遍歷任務的結果for (Future<String> fs : resultList) {try {System.out.println(fs.get()); // 打印各個線程(任務)執行的結果} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();} finally {// 啟動一次順序關閉,執行以前提交的任務,但不接受新任務。如果已經關閉,則調用沒有其他作用。executorService.shutdown();}}} }class TaskWithResult implements Callable<String> {private int id;public TaskWithResult(int id) {this.id = id;}public String call() throws Exception {System.out.println("call()方法被自動調用,干活!!! " + Thread.currentThread().getName());// 一個模擬耗時的操作for (int i = 999999; i > 0; i--);return "call()方法被自動調用,任務的結果是:" + id + " " + Thread.currentThread().getName();} }參考:https://blog.csdn.net/w2393040183/article/details/52177572
http://murielily.blog.163.com/blog/static/134260649201131215237637/
?
總結
以上是生活随笔為你收集整理的Java 的Runnable和Callable的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pytorch的C++接口实践
- 下一篇: 一次惨痛的装机经历