在线程池使用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对象,即执行的结果.下面简要介绍一下两者的三个 ...
随机推荐
- Linux中强制结束一个进程的终极方法
在 Linux Ubuntu 服务器上用 dnx 基于 Kestrel 成功运行一个 ASP.NET 5 站点后,怎么也无无法退出. 运行的命令如下: /data/git/dnx/artifacts/ ...
- 轻松实现ajax登录时让浏览器保存密码
将登录页面由form提交改为ajax提交,发现一个副作用——登录时浏览器不会提示是否保存密码,这样每次登录都要输入用户名/密码. html代码如下: <script> $(function ...
- PHP合成图片、生成文字、居中对齐、画线、矩形、三角形、多边形、图片抗锯齿、不失真 高性能源码示例
function generateImg($source, $text1, $text2, $text3, $font = './msyhbd.ttf') { $date = '' . date ( ...
- 创建链接服务器(dblink)
--创建链接服务器(dblink) exec sp_addlinkedserver 'srv_lnk','','SQLOLEDB','远程服务器名或ip地址' exec sp_addlinkedsrv ...
- 倔强的网站数据抓取,关键时刻还需Webbrowser显身手
由于最近台风挺多,公司网站上需要挂上台风预报信息,就整了个抓取台风数据(至于抓数据的概念和实践手册我以前写的一篇博客里面有介绍:分享一套抓数据小程序,客户资料.实时新闻.股票数据…随心抓)的服务,做调 ...
- [BTS] Error biztalk arguments null exception string reference not set to an instance of a string. parameter name
biztalk arguments null exception string reference not set to an instance of a string. parameter name ...
- 错误The request sent by the client was syntactically incorrect ()的解决
http://www.cnblogs.com/xiandedanteng/p/4168609.html 这个错误是SpringMVC报出来的,见到它意味着html/jsp页面的控件名称 和 contr ...
- 在php中,如何将一个页面中的标签,替换为用户想输出的内容
前言:釜山行,暴露人性, ———————————————————————————————————————————————————————————————————————————— 今天说一个最简单的例 ...
- Liferay7 BPM门户开发之30: 通用帮助类Validator、ArrayUtil、StringUtil等使用
废话不多说,直接上代码. 验证类Validator 主要是空验证.数字.格式验证 调用的例子: protected void validateEmailFrom(ActionRequest actio ...
- 关于iReport报表的分页
问题:二手车认证系统的检测报告采用iReport开发,开发者自定义了一张超级长的纸张,导致打印时自动缩放到了一张A4纸上.需要修改使之能够合理的分页打印,这是来到新公司的第一个任务. 解决方案一: 1 ...