Java 的Runnable和Callable的区别
Runnable和Callable的區(qū)別是,
(1)Callable規(guī)定的方法是call(),Runnable規(guī)定的方法是run().
(2)Callable的任務(wù)執(zhí)行后可返回值,而Runnable的任務(wù)是不能返回值得
(3)call方法可以拋出異常,run方法不可以
(4)運(yùn)行Callable任務(wù)可以拿到一個(gè)Future對(duì)象,表示異步計(jì)算的結(jié)果。它提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并檢索計(jì)算的結(jié)果。通過Future對(duì)象可以了解任務(wù)執(zhí)行情況,可取消任務(wù)的執(zhí)行,還可獲取執(zhí)行結(jié)果。
1.1使用Runnble接口?創(chuàng)建線程
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();} }或者使用匿名類實(shí)現(xiàn):
Thread thread =new Thread(new Runnable() {public void run() {// TODO Auto-generated method stubSystem.out.println("匿名類實(shí)現(xiàn)線程");}使用1.2 使用 Executors 創(chuàng)建線程
package com.asiainfo.proxydemo;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class ThreadExecutorService {//設(shè)置線程的數(shù)量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 創(chuàng)建線程
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()+"通過實(shí)現(xiàn)Callable接口通過FutureTask包裝器來(lái)實(shí)現(xiàn)線程");return null;}}? ? ?2.2 使用 Executors 結(jié)合Callable 創(chuàng)建多線程
? ? ? 在Java5之 后,任務(wù)分兩類:一類是實(shí)現(xiàn)了Runnable接口的類,一類是實(shí)現(xiàn)了Callable接口的類。兩者都可以被ExecutorService執(zhí)行,但是 Runnable任務(wù)沒有返回值,而Callable任務(wù)有返回值。并且Callable的call()方法只能通過ExecutorService的 submit(Callable<T> task) 方法來(lái)執(zhí)行,并且返回一個(gè) <T> Future<T>,是表示任務(wù)等待完成的 Future.
public interface Callable<V>返回結(jié)果并且可能拋出異常的任務(wù)。實(shí)現(xiàn)者定義了一個(gè)不帶任何參數(shù)的叫做 call 的方法。
Callable 接口類似于 Runnable,兩者都是為那些其實(shí)例可能被另一個(gè)線程執(zhí)行的類設(shè)計(jì)的。但是 Runnable 不會(huì)返回結(jié)果,并且無(wú)法拋出經(jīng)過檢查的異常。
Executors 類包含一些從其他普通形式轉(zhuǎn)換成 Callable 類的實(shí)用方法。
Callable中的call()方法類似Runnable的run()方法,就是前者有返回值,后者沒有。
當(dāng)將一個(gè)Callable的對(duì)象傳遞給ExecutorService的submit方法,則該call方法自動(dòng)在一個(gè)線程上執(zhí)行,并且會(huì)返回執(zhí)行結(jié)果Future對(duì)象。
同樣,將Runnable的對(duì)象傳遞給ExecutorService的submit方法,則該run方法自動(dòng)在一個(gè)線程上執(zhí)行,并且會(huì)返回執(zhí)行結(jié)果Future對(duì)象,但是在該Future對(duì)象上調(diào)用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>>();// 創(chuàng)建10個(gè)任務(wù)并執(zhí)行for (int i = 0; i < 10; i++) {// 使用ExecutorService執(zhí)行Callable類型的任務(wù),并將結(jié)果保存在future變量中Future<String> future = executorService.submit(new TaskWithResult(i));// 將任務(wù)執(zhí)行結(jié)果存儲(chǔ)到List中resultList.add(future);}// 遍歷任務(wù)的結(jié)果for (Future<String> fs : resultList) {try {System.out.println(fs.get()); // 打印各個(gè)線程(任務(wù))執(zhí)行的結(jié)果} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();} finally {// 啟動(dòng)一次順序關(guān)閉,執(zhí)行以前提交的任務(wù),但不接受新任務(wù)。如果已經(jīng)關(guān)閉,則調(diào)用沒有其他作用。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()方法被自動(dòng)調(diào)用,干活!!! " + Thread.currentThread().getName());// 一個(gè)模擬耗時(shí)的操作for (int i = 999999; i > 0; i--);return "call()方法被自動(dòng)調(diào)用,任務(wù)的結(jié)果是:" + id + " " + Thread.currentThread().getName();} }參考:https://blog.csdn.net/w2393040183/article/details/52177572
http://murielily.blog.163.com/blog/static/134260649201131215237637/
?
總結(jié)
以上是生活随笔為你收集整理的Java 的Runnable和Callable的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pytorch的C++接口实践
- 下一篇: 一次惨痛的装机经历