- 浏览: 511372 次
- 性别:
- 来自: 深圳
最新评论
-
di1984HIT:
学习了~~
jackson JSON对象映射出多余字段的bug -
lvye351:
当然,在tomcat还有JPDA这种方式 ,来远程debug: ...
配置linux下tomcat的远程debug -
hety163:
好,语言简单明了易懂
Http和Socket连接区别 -
高军威:
<b>行不行</b>
XSS转码 && struts2 property标签的bug -
chjy1983:
请教下,我这样:JSONObject jsonObject = ...
HttpClient4 POST数据及问题
关于ExecutorService好用的方面就不说了,effective java里面是强烈推荐使用Executor代替自己管理Thread。
e.g.
public static void startReceiver() { ExecutorService pool = Executors.newFixedThreadPool(rec_thread_count); pool.execute(new MsgQReceiver()); }
下面看看今天我郁闷的地方:
1.JDK doc里面描述的线程池关闭方法:先暂停接受新任务进来,然后terminate运行中的线程。看起来确实是一个非常完美的方案。
void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); // Disable new tasks from being submitted try { // Wait a while for existing tasks to terminate if (!pool.awaitTermination(60, TimeUnit.SECONDS)) { pool.shutdownNow(); // Cancel currently executing tasks // Wait a while for tasks to respond to being cancelled if (!pool.awaitTermination(60, TimeUnit.SECONDS)) System.err.println("Pool did not terminate"); } } catch (InterruptedException ie) { // (Re-)Cancel if current thread also interrupted pool.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } }
2.分析里面的shutdownNow()实现,发现居然是用的thread.interrupt()。
public List<Runnable> shutdownNow() { /* * shutdownNow differs from shutdown only in that * 1. runState is set to STOP, * 2. all worker threads are interrupted, not just the idle ones, and * 3. the queue is drained and returned. */ SecurityManager security = System.getSecurityManager(); if (security != null) security.checkPermission(shutdownPerm); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { if (security != null) { // Check if caller can modify our threads for (Worker w : workers) security.checkAccess(w.thread); } int state = runState; if (state < STOP) runState = STOP; try { for (Worker w : workers) { w.interruptNow(); } } catch (SecurityException se) { // Try to back out runState = state; // tryTerminate() here would be a no-op throw se; } List<Runnable> tasks = drainQueue(); tryTerminate(); // Terminate now if pool and queue empty return tasks; } finally { mainLock.unlock(); } }
3.在jdk5之后,线程的stop()方法已经被不推荐使用,并且没有替代品。文档上如是说:
建议线程通过里面设置boolean runflag,不停轮询该变量来确定是否继续执行(具体做法可以参考下面我的demo)
Deprecated. This method is inherently unsafe. Stopping a thread with Thread.stop causes it to
unlock all of the monitors that it has locked 。 Many uses of stop should be replaced by code that
simply modifies some variable to indicate that the target thread should stop running.
The target thread should check this variable regularly, and return from its run method in an orderly
fashion if the variable indicates that it is to stop running. If the target thread waits for long periods
(on a condition variable, for example), the interrupt method should be used to interrupt the wait.
4.恰不碰巧,我放进去的thread本身就会有很多sleep()操作,
sleep会在本线程被interrupt的时候抛异常,
/** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds, subject to * the precision and accuracy of system timers and schedulers. The thread * does not lose ownership of any monitors. * * @param millis the length of time to sleep in milliseconds. * @exception InterruptedException if any thread has interrupted * the current thread. The <i>interrupted status</i> of the * current thread is cleared when this exception is thrown. * @see Object#notify() */ public static native void sleep(long millis) throws InterruptedException;
interrupte方法如是说明:
If this thread is blocked in an invocation of the wait()
, wait(long)
, or wait(long,
int)
methods of the Object
class, or of the join()
, join(long)
, join(long,
int)
, sleep(long)
, or
sleep(long,
int)
, methods of this class, then its interrupt status will be
cleared and it will receive an InterruptedException
.
那么使用ExecutorService来关闭我下面这些线程,碰到可能都会是抛出InterruptedException 。走到异常流程并非
优雅的方式,也就失去了步骤1中的意义。
while(runflag) { //do your business try { Thread.sleep(30); } catch (InterruptedException e) { logger.error("msg收取线程sleep异常", e); } } else if (stRet.iRet == -1) { // 没收到消息!! try { Thread.sleep(1000); } catch (InterruptedException e) { logger.error("msg收取线程sleep异常", e); } } else { try { Thread.sleep(2000); } catch (InterruptedException e) { logger.error("msg收取线程sleep异常", e); } }
end:
于是乎,只好回归原始.自己通过改变runflag来友好的关闭线程。
public static void startReceiver() {
for(int i=0;i<rec_thread_count;i++) {
MsgQReceiver rec = new MsgQReceiver();
group.add(rec);
rec.start();
}
// ExecutorService pool = Executors.newFixedThreadPool(rec_thread_count);
// pool.execute(new MsgQReceiver());
}
/** * 终止消息接收线程组 */ public static void stopReceiver() { if(group.size()>0) { for(MsgQReceiver rec : group) { rec.runflag = false; } } group = null; }
评论
executerService.shutdown会调用中断让线程退出,因此在处理任务的时候一定要恰当处理interrupt,否则线程也退不出来。
后来我改为控制runflag,而不是依赖ExecutorService
更准确的说是对如何停止一个线程有误解.
企图通过调用一个类似stop语义的方法停止或者杀死一个线程的想法从设计上就是错误的.线程的合理中止本质上就是个很复杂的事情,想通过外部代码直接杀死一个线程,直接的结果就是导致资源的泄漏,事务的不完整或者业务的缺失,如果从语言级别支持这种特性,带来的一定是无穷无尽的后患.你把一系列动作交给一个线程,但是又不想去规划它,而是想通过一个stop随性的想停就停本身就是个不负责的想法.
runflag的变量也应该跟着变化。
代码再慢慢看,先顶上
发表评论
-
Nginx rewrite permanent
2014-03-19 16:43 1764fpm之后,尝试兼容url错误的一段redirect失效。具 ... -
ZmEu漏洞扫描
2014-02-21 16:59 7478挺黑的,nginx抓出来的日志。扫描各种php软件、数据库 ... -
Continuous Integration with Xcode 5
2014-01-09 15:04 996xcode5 及持续集成, 花了20分钟上手配置, 效果非 ... -
Httpclient4.3实例。 每个版本接口变更都巨大
2014-01-08 17:55 33531.新增简单的url请求内容返回, 比较时髦的链调用 ... -
nginx proxy_http_version
2014-01-07 16:10 6375nginx转 apache ,发现HTTP协议版本 从1.1 ... -
ubuntu一键升级到13.10的教训
2013-12-16 11:51 1106从13.04升级到13.10,主要两个变化非常蛋疼: 1 ... -
【PHP】Codeigniter : Unable to locate the model you have specified
2013-12-10 11:36 1916产生这个问题一般两个原因: 1. google到的结果,类 ... -
springMVC + jsonP
2013-11-20 12:58 4198/** * 根据分类id,取新闻列表 ... -
PC端 浏览器Agent切换工具
2013-11-18 11:04 1057插件比较方便,技术流还是推荐fiddler -
Spring3.x中的几个异步执行
2013-08-22 15:00 29041.servlet3 细节可以阅读http://www.i ... -
Mybatis Cache探究
2013-08-22 12:01 1983这里先不讨论第三方的cache集成(有memcach ... -
spring3-基于注解的AOP
2013-08-02 11:58 1044要点: 1.aop的概念真的很多。。。其实从使用出发无非 ... -
HttpClient4 POST数据及问题
2012-05-23 18:03 33600post 方式挂参数的三种格式, mark一下。 ... -
struts2-ognl mark
2011-12-29 16:49 1580暂时mark在这,后面再补充 1. 关于漏洞的问 ... -
类模板语言的变量替换~简易java实现
2011-04-06 15:25 3722场景1:数据库存有 xx,y ... -
XSS转码 && struts2 property标签的bug
2011-03-25 15:36 6683一。了解背景 下面两张图,比较html转义和js的转义。 ... -
小折腾一下swing
2011-03-23 16:23 1214近来看美剧《Lost》,可惜下载的rm文件名太长,很难找到自己 ... -
FileUploadInterceptor ~mark陷阱
2011-03-17 15:45 165503/17 14:25:40 [ERRO ... -
新浪微博技术架构分析-转载
2011-03-07 17:07 2135中国首届微博开发者大会在北京举行,这是国内微博行业的首场技术盛 ... -
谨慎使用SocketChannel的read方法
2011-01-13 18:02 6047下面的代码是一个实例化SocketChannel的过程: ...
相关推荐
在 Spring Boot 中使用 Java 线程池 ExecutorService 的讲解 Spring Boot 作为一个流行的 Java 框架,提供了许多便捷的功能来帮助开发者快速构建应用程序。其中之一就是使用 Java 线程池 ExecutorService 来管理...
ExecutorService方法案例文件.zip
ExecutorService 和 CompletionService 是Java并发处理中的两种工具,它们用于管理和执行多个任务。ExecutorService 是一个接口,它是java.util.concurrent.Executor 接口的扩展,提供了一组方法来管理和控制线程池...
接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。壹個 ExecutorService 实例因此特别像壹個线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现...
ExecutorService线程池是Java并发编程中的核心组件,它位于`java.util.concurrent`包下,是`java.util.concurrent.Executor`接口的一个实现。ExecutorService提供了一种管理线程的方式,允许我们创建、管理和控制...
在Java多线程编程中,`ExecutorService`是线程池的核心接口,它提供了一种管理线程的方式,包括创建线程、调度线程执行以及控制线程的生命周期。`ExecutorService`通过`execute()`和`submit()`这两个方法来提交任务...
在Java并发编程中,`Executor`、`Executors`和`ExecutorService`是核心组件,它们帮助开发者高效管理线程资源,提高程序的并发性能。理解这三个概念的区别和用途是编写高性能并发程序的关键。 1. **Executor** `...
总结一下,`ExecutorService.shutdown()`方法的正确理解是它会在等待所有正在执行的任务完成后再关闭线程池,而不是立即停止所有活动。这与`shutdownNow()`方法形成对比,后者试图立即停止正在执行的任务。了解这些...
Java中的`ExecutorService`是Java并发编程的重要组成部分,它提供了线程池的管理,使得开发者可以更有效地控制并发任务的执行。在Java的`java.util.concurrent`包中,`ExecutorService`接口作为线程池的核心接口,...
运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接
ExecutorService可以创建固定大小的线程池,也可以创建缓存线程池、调度线程池等。 在上面的代码中,我们使用了Executors.newFixedThreadPool方法创建了一个固定大小的线程池,大小为4。然后,我们提交了四个Task1...
NULL 博文链接:https://x125858805.iteye.com/blog/2191873
Java中的ExecutorService是Java并发编程的重要组成部分,它提供了一种高效、灵活的方式来管理和控制线程的...同时,合理地关闭ExecutorService(通过`shutdown()`或`shutdownNow()`方法)也是防止资源泄漏的关键步骤。
主要介绍了java中Executor,ExecutorService,ThreadPoolExecutor详解的相关资料,需要的朋友可以参考下
ExecutorService 是 Java 中用于管理和控制线程执行的核心接口,它是 java.util.concurrent 包的一部分。ExecutorService 扩展了 Executor 接口,提供了更丰富的功能,如任务的提交、关闭服务、检查服务状态等。这个...
标题 "2011.08.30(2)——— java BlockingQueue ExecutorService" 涉及到Java并发编程中的两个核心组件:BlockingQueue(阻塞队列)和ExecutorService。这篇博客可能深入探讨了如何使用这两个工具来优化多线程环境...
Java线程池ExecutorService是Java并发编程中非常重要的一个组件,它通过管理和复用线程资源,有效地控制并发任务的执行,从而提高系统的性能和稳定性。本文将详细讲解ExecutorService的原理、使用场景以及如何通过...
Java 使用 ExecutorService 来停止线程服务 Java 中的 ExecutorService 是一个非常强大...同时,我们也可以继承 AbstractExecutorService 类来自定义一个 ExecutorService,以获取开始执行但是还没有执行完毕的任务。
Java并发编程中的Executor、Executors和ExecutorService是Java并发编程框架的重要组成部分,它们为开发者提供了高效管理和控制线程执行的工具。以下是对这些概念的详细解释: 1. Executor: Executor是一个接口,它...
在Java编程中,`ExecutorService`是Java并发包(`java.util.concurrent`)中的核心接口,它提供了一种管理和控制线程的方式。在处理Socket连接时,尤其是TCP和UDP通信,`ExecutorService`可以帮助我们有效地利用系统...