一、区别总结:

  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. hmailserver

    开始使用: www.hmailserver.org 问题 让hmailserver的用户使用各自的中继来发送邮件: http://dagai.net/archives/968

  2. 设计模式之美:Chain of Responsibility(职责链)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现后继者链. 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系. 将这些对象连成一条链,并沿着这条 ...

  3. 团队项目 SRS文档

    一:实验内容:用例模型的建立 简介: 图书管理系统是使用计算机实现图书大量信息处理的电子档案管理系统,在本系统中主要满足借书者.图书管理员和系统管理员3方面的需求.对借书者来说主要是查询个人信息.查询 ...

  4. memcached与.NET的融合使用(二)

    memcached部署完成之后,对当前缓存中数据的监控就显得比较迫切,这里看到网上开源的memadmin比较小巧好用,决定用它来查看监控memcached. 下载memadmin1.0.11,地址:h ...

  5. Git可视化极简易教程 —— Git GUI使用方法

    前言 之前一直想一篇这样的东西,因为最初接触时,我也认真看了廖雪峰的教程,但是似乎我觉得讲得有点多,而且还是会给我带来很多多余且重复的操作负担,所以我希望能压缩一下它在我工作中的成本,但是搜索了一下并 ...

  6. paip.突破 网站 手机 验证码 的 破解 总结

    paip.突破 网站 手机 验证码 的 破解 总结  作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...

  7. Apache JMeter 测试Http请求

    环境安装:JDK 下载:http://jmeter.apache.org/download_jmeter.cgi 启动: 简单HTTP请求测试

  8. JavaScript 语句 while

    while 语句用法 与for语句的用法之间的关系 for(i==1;i<5;i++) {document.write("12378<br />")  } 若使用 ...

  9. DataGridViewComboBoxColumn值无效

    值无效,可能是你下拉框选项,没有这样的值,而你却设置这个值. dataGridView1.Rows[i].Cells[].Value = "选项一"; 解决方法就是在窗体的构造函数 ...

  10. android: 调用摄像头拍照

    很多应用程序都可能会使用到调用摄像头拍照的功能,比如说程序里需要上传一张图片 作为用户的头像,这时打开摄像头拍张照是最简单快捷的.下面就让我们通过一个例子来学 习一下,如何才能在应用程序里调用手机的摄 ...