在线程池使用Callable和Runnable的区别以及如何关闭线程
一、区别总结:
- Callable定义的方法是call,而Runnable定义的方法是run。
- Callable的call方法可以有返回值,而Runnable的run方法不能有返回值,这是核心区别。
- 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的区别以及如何关闭线程的更多相关文章
- 多线程----Thread类,Runnable接口,线程池,Callable接口,线程安全
1概念 1.1进程 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 任务管理器中: 1.2线程 线程是进程中的一个执行单元 ...
- java多线程(三)-Executors实现的几种线程池以及Callable
从java5开始,类库中引入了很多新的管理调度线程的API,最常用的就是Executor(执行器)框架.Executor帮助程序员管理Thread对象,简化了并发编程,它其实就是在 提供了一个中间层, ...
- JAVA 线程池之Callable返回结果
本文介绍如何向线程池提交任务,并获得任务的执行结果.然后模拟 线程池中的线程在执行任务的过程中抛出异常时,该如何处理. 一,执行具体任务的线程类 要想 获得 线程的执行结果,需实现Callable接口 ...
- Java线程池(Callable+Future模式)
转: Java线程池(Callable+Future模式) Java线程池(Callable+Future模式) Java通过Executors提供四种线程池 1)newCachedThreadPoo ...
- 【转】线程池体系介绍及从阿里Java开发手册学习线程池的正确创建方法
jdk1.7中java.util.concurrent.Executor线程池体系介绍 java.util.concurrent.Executor : 负责线程的使用与调度的根接口 |–Execut ...
- Java线程池 / Executor / Callable / Future
为什么需要线程池? 每次都要new一个thread,开销大,性能差:不能统一管理:功能少(没有定时执行.中断等). 使用线程池的好处是,可重用,可管理. Executor 4种线程 ...
- 线程池使用Callable示例【我】
实际工作中可以把下面的代码直接拿过去改改即可 package threadtest; import java.util.ArrayList; import java.util.HashMap; imp ...
- 线程池与Callable接口
定义: 一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源. 使用方法 public void lockDemo() throws Inter ...
- 线程池的submit和execute方法区别
线程池中的execute方法大家都不陌生,即开启线程执行池中的任务.还有一个方法submit也可以做到,它的功能是提交指定的任务去执行并且返回Future对象,即执行的结果.下面简要介绍一下两者的三个 ...
随机推荐
- HTML5服务器端推送事件 解决PHP微信墙推送问题
问题描述 以前的文章中<PHP微信墙制作,开源>已经用PHP搭建了一个微信墙获取信息的服务器,然后我就在想推送技术应该怎么解决,上一篇已经用了.NET 的signalr做了一个微信墙,PH ...
- iPhone中修改iMessage关联手机号码的终极方法
同事换iPhone时,也换了手机号码,从联通的换成移动的.但iPhone激活后,iMessage始终关联的是以前的手机号码,试了很多方法都没解决. 后来在网上找到一段视频-Fix most iMess ...
- 傻逼Eclipse笔记
Eclipse 这么傻逼的工具,还有人用,真是奇了怪了. Invalid project description 我想打开SVN 的代码 ,别让我拷到别的地方,怎么破? 正确答案是: 删除 Eclip ...
- 无环的visitor模式
无环的访问者模式,是来改进原有访问者模式的不足之处的,是Robert C. Martin首次提出的.我们知道访问者模式的优点是为被访问继承体系动态添加行为,而无须改变继承体系.但是GOF访问者模式的缺 ...
- Windows Azure 使用体验
本文只是对Windows Azure的肤浅使用做个记录,算是简单入门吧. 一.门户网站 Windows Azure其实有两个版本,我们在国内所说的或者说所用的就是有别于国际版的,主要原因我想各位也是知 ...
- Lingo 做线性规划 - Asset allocation and Portfolio models
Reference: <An Introduction to Management Science Quantitative Approaches to Decision Making, Rev ...
- Could not load file or assembly 'System.Data.SQLite' or one of its dependencies. 试图加载格式不正确的程序。
出现上述问题的原因是,所加载的程序集中有32位的,也有64位的,IIS 7 程序池 在Windows下.Net FrameWork是64位的,要想正确使用,需要对程序池进行配置.如下图所示:
- JavaScript-冒泡排序
随机生成10个不重复的100以内的整数放入数组,并排序后进行打印<br /> 如: for(var i=0;i<9;i++) { for(var j=i+1;j<9;j++) ...
- iOS开发——高级技术&通讯录功能的实现
通讯录功能的实现 iOS 提供了对通讯录操作的组建,其中一个是直接操作通讯录,另一个是调用通讯录的 UI 组建.实现方法如下: 添加AddressBook.framework到工程中. 代码实现: 1 ...
- JDK版本不兼容问题之:一台机器安装多个版本的JDK
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://guojie.blog.51cto.com/59049/45964 我的机器上最开 ...