一、区别总结:

  1. Callable定义的方法是call,而Runnable定义的方法是run。
  2. Callable的call方法可以有返回值,而Runnable的run方法不能有返回值,这是核心区别。
  3. Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。

二、返回值的区别

他们的核心区别是Callable可以返回Feature的对象,这个对象可以了解线程的运行情况,设置可以关闭线程!

三、Runnable代码事例

package com.qunar.synchro;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Created by qiu.li on 2015/9/21.
* 这是一个继承Runnable的例子
*/
public class TestRunnable implements Runnable { public static void main(String[] args) { ExecutorService runnableService = Executors.newFixedThreadPool(3); Runnable r1 = new TestRunnable();
runnableService.submit(r1);
runnableService.submit(new TestRunnable());
runnableService.submit(new TestRunnable());
runnableService.submit(new TestRunnable());
runnableService.shutdown(); System.out.println("go on");
System.out.println("end");
} @Override
public void run() {
for(int i=0;i<5; i++) {
System.out.println(Thread.currentThread().getName() + ";random:" + (int) (Math.random() * 10 * 1000));
try {
Thread.sleep( (int) (Math.random() * 10 * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

他的输出也比较简单,

pool-1-thread-2;random:9491
go on
end
pool-1-thread-3;random:6983
pool-1-thread-1;random:718
pool-1-thread-2;random:4214..... Process finished with exit code 0

四、Callable代码

package com.qunar.synchro;

import com.sun.org.apache.xalan.internal.utils.FeatureManager;

import java.util.concurrent.*;

/**
* Created by qiu.li on 2015/9/21.
*/
public class TestCallable implements Callable<Boolean> { int i; public static void main(String[] args) { ExecutorService runnableService = Executors.newFixedThreadPool(3); Future<Boolean> r1 = runnableService.submit(new TestCallable(1));
Future<Boolean> r2 = runnableService.submit(new TestCallable(2));
Future<Boolean> r3 = runnableService.submit(new TestCallable(3));
try {
boolean b2 = r2.get(); //r2先跑
boolean b3 = r3.get(); //r3先跑
System.out.println(b2);
System.out.println(b3);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
r1.cancel(true);//r1是死循环,现在退出
runnableService.shutdownNow();
} public TestCallable(int i){
this.i = i;
} @Override
public Boolean call() {
try {
switch (i){
case 1:
while(true) {
System.out.println(Thread.currentThread().getName() + ";i:" + this.i); //第一个线程
Thread.sleep(200);
}
default:
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + ";i:" + this.i); //其他线程
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
}

运行的结果:

pool-1-thread-1;i:1
pool-1-thread-1;i:1
pool-1-thread-1;i:1
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.qunar.synchro.TestCallable.call(TestCallable.java:46)
at com.qunar.synchro.TestCallable.call(TestCallable.java:10)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
pool-1-thread-2;i:2
pool-1-thread-3;i:3
true
true Process finished with exit code 0

大家可以看见抛出的异常,这是因为在线程1被阻塞的时候(比如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时),由于没有占用CPU,是不能给自己的中断状态置位的,这就会产生一个InterruptedException异常。

在线程池使用Callable和Runnable的区别以及如何关闭线程的更多相关文章

  1. 多线程----Thread类,Runnable接口,线程池,Callable接口,线程安全

    1概念 1.1进程 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 任务管理器中: 1.2线程 线程是进程中的一个执行单元 ...

  2. java多线程(三)-Executors实现的几种线程池以及Callable

    从java5开始,类库中引入了很多新的管理调度线程的API,最常用的就是Executor(执行器)框架.Executor帮助程序员管理Thread对象,简化了并发编程,它其实就是在 提供了一个中间层, ...

  3. JAVA 线程池之Callable返回结果

    本文介绍如何向线程池提交任务,并获得任务的执行结果.然后模拟 线程池中的线程在执行任务的过程中抛出异常时,该如何处理. 一,执行具体任务的线程类 要想 获得 线程的执行结果,需实现Callable接口 ...

  4. Java线程池(Callable+Future模式)

    转: Java线程池(Callable+Future模式) Java线程池(Callable+Future模式) Java通过Executors提供四种线程池 1)newCachedThreadPoo ...

  5. 【转】线程池体系介绍及从阿里Java开发手册学习线程池的正确创建方法

    jdk1.7中java.util.concurrent.Executor线程池体系介绍 java.util.concurrent.Executor : 负责线程的使用与调度的根接口  |–Execut ...

  6. Java线程池 / Executor / Callable / Future

    为什么需要线程池?   每次都要new一个thread,开销大,性能差:不能统一管理:功能少(没有定时执行.中断等).   使用线程池的好处是,可重用,可管理.   Executor     4种线程 ...

  7. 线程池使用Callable示例【我】

    实际工作中可以把下面的代码直接拿过去改改即可 package threadtest; import java.util.ArrayList; import java.util.HashMap; imp ...

  8. 线程池与Callable接口

    定义: 一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源. 使用方法 public void lockDemo() throws Inter ...

  9. 线程池的submit和execute方法区别

    线程池中的execute方法大家都不陌生,即开启线程执行池中的任务.还有一个方法submit也可以做到,它的功能是提交指定的任务去执行并且返回Future对象,即执行的结果.下面简要介绍一下两者的三个 ...

随机推荐

  1. [游戏模版17] Win32 推箱子 迷宫

    >_<:Here introduce a simple game: >_<:resource >_<:only can push a box and finally ...

  2. 用dom操作替代正则表达式

    在B/S结构客户端越来越“胖”的今天,作为一名全端程序员,您很可能会在前端操作html字符串,注意,是操作html字符串,不是操作当前页面的html. 举个例子,百度推出的在线HTML富文本编辑器Ue ...

  3. 使用Nito.AsyncEx实现异步锁

    Lock是常用的同步锁,但是我们无法在Lock的内部实现异步调用,比如我们无法使用await. 以下面的代码为例,当你在lock内部使用await时,VS会报错提醒. 最简单的解决办法就是使用第三方的 ...

  4. 【转】关于KDD Cup '99 数据集的警告,希望从事相关工作的伙伴注意

    Features From: Terry Brugger Date: 15 Sep 2007 Subject: KDD Cup '99 dataset (Network Intrusion) cons ...

  5. Atitti.java exp ast java表达式语法ast构造器

    Atitti.java exp ast java表达式语法ast构造器 /atiplat_cms/src/com/attilax/lang/AstParser.java 原理 分割tokens_sli ...

  6. atitit.提升开发效率---动态语言总结

    atitit.提升开发效率---动态语言总结 ruby,python 都不错,就是语法不好, 应用不广泛,文档,工具都非常少,不推荐... php狠不错,就是高级特性不行.. 看来子有.net/jav ...

  7. fir.im Weekly - 新开发时代,每个人都在创造

    七夕纷纷扰扰地过去了,身边的程序员们依旧安静从容地写代码.可是满屏幕的"对象",不如身边一个对象(。・`ω´・)- 闲话说完,这周像往期一样为大家收集了一些优秀的 GitHub 资 ...

  8. 让delphi解析chrome扩展的native应用

    chrome浏览器自从去年以来逐步去掉了对浏览器插件的支持,npapi的方案马上不可用. 当务之急要选择一个替代方案,最常用的就是扩展了.扩展程序提供了一套和本地程序交互的方案——“原生消息通信” 写 ...

  9. AsyncTask实现断点续传

    之前公司里面项目的下载模块都是使用xUtils提供的,最近看了下xUtils的源码,它里面也是使用AsyncTask来执行异步任务的,它的下载也包含了断点续传的功能.这里我自己也使用AsyncTask ...

  10. 打包.a 文件时, build phases- Link Binary With Libraries

    打包.a 文件时, 如果是两个Targets那么可运行调试的  build phases-  Link Binary With Libraries  如果加入.a 文件. 那么就不需要在Compile ...