一、区别总结:

  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. ASP.NET前端解决方案之一:Ext.Net入门随笔1

    最近因为公司需要,进一步研发了Ext.Net技术,这里先做一个简明的介绍,给自己和大家记录一个初步的概念. 什么是Ext Ext就是ExtJS,引用下百度的解释:“ExtJS是一种主要用于创建前端用户 ...

  2. 【Win10】解决 模拟器调试手机 错误-> 引导阶段... 无法找到指定路径......\2052\msdbgui.dll

    去弄几天的Web服务,又弄了几天的CefSharp,都是给其它组的同学做了一下支持,终于又可以回来玩下Win10啦. 今天想试一下UWP在手机上的效果,就找了台WP手机开始升级,结果下载速度遥遥无期, ...

  3. [Hyper-V]使用操作系统模板创建新的虚拟机

    描述: 为了节省空间和时间的目的,先在Hyper-V里创建一个干净的操作系统,以后再创建虚拟机时都基于此操作系统,节省了安装Windows的时间 另外创建其它虚拟机的时候,也以上述虚拟机的磁盘为基础盘 ...

  4. Mac系统下lipo, ar, nm等工具的使用简介

    引言 开发第三方库时, 如果没有进行特殊处理, 很容易把其他第三方库的符号暴露出来, 导致链接时产生符号重复. 如下图所示 如果用户链接了其他版本的libjpeg, 会因为入口地址不正确让程序直接崩溃 ...

  5. Atitit.web三大编程模型 Web Page Web Forms 和 MVC

    Atitit.web三大编程模型 Web Page    Web Forms 和 MVC 1. 编程模型是 Web Forms 和 MVC (Model, View, Controller). 2.  ...

  6. atitit.提升开发效率---MDA 软件开发方式的革命(5)----列表查询建模

    )----列表查询建模 1. 配置条件字段@Conditional 1 2. 配置条件字段显示类型为range----@Conditional(displayType = displayType.ra ...

  7. Tamper Data

    一款可以修改表单的火狐浏览器插件

  8. 首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能。(已完善)

    package java1; public class Account { String zhanghao; double yue=0; double add; double get; Account ...

  9. if else重复十多次的业务代码也是醉了

    嗯,一个页面同时刷这8个接口,我说能不能合并到一个网络接口,不用一个页面并发8个请求,他说太长了,不好合并. 我看了一下他代码,也是醉了,写了8个接口,访问的都是一个表,然后每个接口重复if else ...

  10. 为CentOS 6 配置本地YUM源

    在网上找了很多为CentOS 6配置本地YUM源的方法,其中有很多是与网络相关的,我只想配个自己用的,结果就发现这个方法比较简单实用,就转过来了. 环境:CentOS 6.0 默认的yum是以网络来安 ...