- 浏览: 498960 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (200)
- java基础 (30)
- ajax (19)
- 乱写 (5)
- groovy (2)
- db (8)
- gwt (0)
- jee (2)
- 我关注的开源 (1)
- RIA AIR (1)
- spring (11)
- lucene (0)
- 工具 (10)
- 百科 (2)
- linux (6)
- android (40)
- 移动开发 (21)
- 代码片断 (15)
- tomcat (1)
- css (1)
- html5 (2)
- jquery (2)
- playframework (3)
- web (2)
- nio (3)
- design (1)
- nosql (3)
- 日志 (12)
- mysql (4)
- 图表 (1)
- python (3)
- ruby (1)
- git (0)
- hibernate (1)
- springboot (1)
- guava (1)
- mybatis (0)
- 工作问题 (3)
- php (1)
最新评论
-
linzm1990:
踩了很多坑啊。。。。
hibernate @Nofound 与@ManyToOne fetch lazy的问题 -
Ccccrrrrrr:
...
转: Spring boot 文件上传 -
rmzdb:
兄弟,你这个东西,在ie内核的浏览器,貌似不识别 文件名
工作问题:http下载文件,中文文件名在firefox下乱码问题 -
107x:
问题解决了,谢谢!
工作问题:http下载文件,中文文件名在firefox下乱码问题 -
klxqljq:
额鹅鹅鹅
android布局实现头尾固定, 中间多余内容可以滚动
转自: http://www.blogjava.net/killme2008/archive/2007/09/03/142344.html
当外部代码能够在活动自然完成之前,把它的状态更改为完成状态,那么这个活动被称为可取消(cancellable)。取消任务是一个很常见的需求,无论是由于用户请求还是系统错误引起的服务关闭等等原因。最简单的任务取消策略就是在线程中维持一个bool变量,在run方法中判断此变量的bool值来决定是否取消任务。显然,这个bool变量需要声明为volatile,以保持多线程环境下可见性(所谓可见性,就是当一个线程修改共享对象的某个状态变量后,另一个线程可以马上看到修改结果)。下面是一个来自《java并发编程实践》的例子:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class PrimeGenerator implements Runnable {
private final List<BigInteger> primes = new ArrayList<BigInteger>();
private volatile boolean cancelled;
public void run() {
BigInteger p = BigInteger.ONE;
while (!cancelled) {
p = p.nextProbablePrime();
synchronized (this) {
primes.add(p);
}
}
}
public void cancel() {
cancelled = true;
}
public synchronized List<BigInteger> get() {
return new ArrayList<BigInteger>(primes);
}
public static void main(String args[]) throws InterruptedException {
PrimeGenerator generator = new PrimeGenerator();
new Thread(generator).start();
try {
TimeUnit.SECONDS.sleep(1);
} finally {
generator.cancel();
}
}
}
main中启动一个素数生成的任务,线程运行一秒就取消掉。通过线程中的cancelled变量来表征任务是否继续执行。既然是最简单的策略,那么什么是例外情况?显然,阻塞操作下(比如调用join,wait,sleep方法),这样的策略会出问题。任务因为调用这些阻塞方法而被阻塞,它将不会去检查volatile变量,导致取消操作失效。那么解决办法是什么?中断!考虑我们用BlockingQueue去保存生成的素数,BlockingQueue的put方法是阻塞的(当BlockingQueue满的时候,put操作会阻塞直到有元素被take),让我们看看不采用中断,仍然采用简单策略会出现什么情况:
import java.math.BigInteger;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class BrokenPrimeProducer extends Thread {
static int i = 1000;
private final BlockingQueue<BigInteger> queue;
private volatile boolean cancelled = false;
BrokenPrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
BigInteger p = BigInteger.ONE;
try {
while (!cancelled) {
p = p.nextProbablePrime();
queue.put(p);
}
} catch (InterruptedException cusumed) {
}
}
public void cancel() {
this.cancelled = false;
}
public static void main(String args[]) throws InterruptedException {
BlockingQueue<BigInteger> queue = new LinkedBlockingQueue<BigInteger>(
10);
BrokenPrimeProducer producer = new BrokenPrimeProducer(queue);
producer.start();
try {
while (needMorePrimes())
queue.take();
} finally {
producer.cancel();
}
}
public static boolean needMorePrimes() throws InterruptedException {
boolean result = true;
i--;
if (i == 0)
result = false;
return result;
}
}
我们在main中通过queue.take来消费产生的素数(虽然仅仅是取出扔掉),我们只消费了1000个素数,然后尝试取消产生素数的任务,很遗憾,取消不了,因为产生素数的线程产生素数的速度大于我们消费的速度,我们在消费1000后就停止消费了,那么任务将被queue的put方法阻塞,永远也不会去判断cancelled状态变量,任务取消不了。正确的做法应当是使用中断(interrupt):
import java.math.BigInteger;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class PrimeProducer extends Thread {
static int i = 1000;
private final BlockingQueue<BigInteger> queue;
private volatile boolean cancelled = false;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
BigInteger p = BigInteger.ONE;
try {
while (!Thread.currentThread().isInterrupted()) {
p = p.nextProbablePrime();
queue.put(p);
}
} catch (InterruptedException cusumed) {
}
}
public void cancel() {
interrupt();
}
public static void main(String args[]) throws InterruptedException {
BlockingQueue<BigInteger> queue = new LinkedBlockingQueue<BigInteger>(
10);
PrimeProducer producer = new PrimeProducer(queue);
producer.start();
try {
while (needMorePrimes())
queue.take();
} finally {
producer.cancel();
}
}
public static boolean needMorePrimes() throws InterruptedException {
boolean result = true;
i--;
if (i == 0)
result = false;
return result;
}
}
在run方法中,通过Thread的isInterrupted来判断interrupt status是否已经被修改,从而正确实现了任务的取消。关于interrupt,有一点需要特别说明,调用interrupt并不意味着必然停止目标线程的正在进行的工作,它仅仅是传递一个请求中断的信号给目标线程,目标线程会在下一个方便的时刻中断。而对于阻塞方法产生的InterruptedException的处理,两种选择:要么重新抛出让上层代码来处理,要么在catch块中调用Thread的interrupt来保存中断状态。除非你确定要让工作线程终止(如上所示代码),否则不要仅仅是catch而不做任务处理工作(生吞了InterruptedException),更详细可以参考这里。如果不清楚外部线程的中断策略,生搬硬套地调用interrupt可能产生不可预料的后果,可参见书中7.1.4例子。
另外一个取消任务的方法就是采用Future来管理任务,这是JDK5引入的,用于管理任务的生命周期,处理异常等。比如调用ExecutorService的sumit方法会返回一个Future来描述任务,而Future有一个cancel方法用于取消任务。
那么,如果任务调用了不可中断的阻塞方法,比如Socket的read、write方法,java.nio中的同步I/O,那么该怎么处理呢?简单地,关闭它们!参考下面的例子:
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
/**
* 展示对于不可中断阻塞的取消任务 通过关闭socket引发异常来中断
*
* @author Admin
*
*/
public abstract class ReaderThread extends Thread {
private final Socket socket;
private final InputStream in;
public ReaderThread(Socket socket) throws IOException {
this.socket = socket;
this.in = socket.getInputStream();
}
// 重写interrupt方法
public void interrupt() {
try {
socket.close();
} catch (IOException e) {
} finally {
super.interrupt();
}
}
public void run() {
try {
byte[] buf = new byte[1024];
while (true) {
int count = in.read(buf);
if (count < 0)
break;
else if (count > 0)
processBuff(buf, count);
}
} catch (IOException e) {
}
}
public abstract void processBuff(byte[] buf, int count);
}
Reader线程重写了interrupt方法,其中调用了socket的close方法用于中断read方法,最后,又调用了super.interrupt(),防止当调用可中断的阻塞方法时不能正常中断。
发表评论
-
ChartDirectorvk如何测试文本的长度跟宽度
2012-11-30 15:53 1102在使用charDirector画图时, 要确定setPlotA ... -
Java调用外部程序技巧
2012-08-24 13:43 1287http://www.yankay.com/java%E8%B ... -
java中的协变
2012-08-14 09:10 1127协变是指一个类型随着它关联的类型一起变化,有点抽像,java中 ... -
jdbm
2012-07-11 15:20 1309jdbm4也发布部分代码了, ... -
使用java实现grep功能(FileChannel, Pattern, MappedByteBuffer 直接字节缓冲区,其内容是文件的内存映射区域)
2012-02-23 10:42 2932利用正则表达式查找一系列文件,类似于grep功能. 演示了 N ... -
并发--Effective Java的一小段代码
2012-02-20 17:14 1179import java.util.concurrent.T ... -
JAVA使用EPoll来进行NIO处理的方法
2012-02-14 09:20 1003JDK 6.0 以及JDK 5.0 update 9 的 ni ... -
java里的枚举
2011-12-30 15:03 1119参考: http://www.ibm.com/develope ... -
项目中用到的一个小工具类(字符过滤器)
2011-10-25 09:08 1030见: http://javatar.iteye.com/blo ... -
下载处理Servlet工具类
2011-10-25 09:06 940转自 http://javatar.iteye.com/blo ... -
局部类访问外部final变量
2011-01-26 12:21 1116在局部类, 我们要更新封闭作用域用的变量, 这一般来说是不容易 ... -
tomcat开启gzip
2011-01-21 13:46 1182在conf/server.xml中找到第一个Connector ... -
maven中国地址
2011-01-06 13:37 3301maven的中国mirror <mirror> ... -
java范型小记
2010-12-18 17:51 01. Collections.<String>em ... -
jsp里的${}和jquery template的${} 怎么样转义
2010-12-16 14:38 4770ttp://www.infoq.com/cn/news/201 ... -
正则表达式
2010-11-30 08:27 1355由于项目中需要用到正则表达式,再一每次使用正则表达式时都要查资 ... -
Java Web 应用程序的字符编码问题
2010-11-30 08:13 1072Java Web 应用程序经常会出现乱码的情况,这里可以通过 ... -
异常的限制
2010-11-30 08:09 1042java 程序声明异常时,父类的某个方法声明了异常的抛出,那 ... -
JVM参数调优(带JMX)
2010-09-09 08:48 1364JAVA_OPTS='-d64-Djava.rmi.serve ... -
java Bridge method
2010-08-06 15:15 2271bridge method may be create ...
相关推荐
这个资源文件中,包含了停止线程和取消线程任务的案例代码,介绍了四五种停止线程、取消线程任务的方式,有Thread.stop()、Thread.interrupt()、future,cancel(true)等等,也可以查看文章...获取。
定义全局线程池,将用户的请求放入自定义队列中,排队等候线程调用,等待超时则自动取消该任务,实现超时可取消的异步任务
InterruptedException 线程被中断异常, ExecutionException任务执行异常,如果任务被取消,还会抛出CancellationException V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException,...
C#多线程并行管理,通过Task实现,可对单个任务进行暂停,继续以及停止等操作,每个任务均有单独的进度条显示 同时执行的任务个数可以自行设置
使用Quartz调度任务,根据需要人为的终止某个任务,适用于很多常见的场景
详细介绍java并发编程相关知识: 基础知识 并发与并行 Java并发演进历史 Java并发模型 线程模型 存储模型 JVM同步原语 volatile CAS 线程安全 ... 线程的中断与任务的取消 其他
2 ACE_Thread_Manage类线程挂起、继续、取消操作 3 ACE_TSS模板的线程专有变量 4 创建线程和线程互斥 5 动态更换互斥方法 6 使用令牌互斥方法 7 守卫锁也是自动锁方法 8 条件等待 9 线程同步栅栏 10 主动对象创建...
Demo_GridViewActivity 队列任务管理 线程控制 Demo_GridViewActivity方式 1:队列优先级 (如果想要listview中移动的区域优先被显示,而不是从上到下显示图片,可以把新建的任务提到任务队列前端) 2:实现了...
4. 问题定位:打印3台机器的worker进程dump信息,发现215、216机器上,处理停止任务的线程发生了 一直 waiting 状态,找到 5. 解决方案:去掉processUtils.killYarnJob逻辑(hive、spark客户端执行,只需kill 本地...
需要取消所有1v1管理线程,在此需要一个列表保存这些线程的ID 需要清理表当中的互斥锁和信号变量,如果1).1.是动态分配,要释放 3)关于改进: 1. 回收资源的线程和TaskList reclaim[LEVEL_ARRAY_LIMIT];是可以...
7.1 任务取消 7.2 停止基于线程的服务 7.3 处理反常的线程终止 7.4 jvm关闭 第8章 应用线程池 8.1 任务与执行策略问的隐性耦合 8.2 定制线程池的大小 8.3 配置threadpoolexecutor 8.4 扩展threadpoolexecutor 8.5 ...
7.1 任务取消 7.2 停止基于线程的服务 7.3 处理反常的线程终止 7.4 jvm关闭 第8章 应用线程池 8.1 任务与执行策略问的隐性耦合 8.2 定制线程池的大小 8.3 配置threadpoolexecutor 8.4 扩展threadpoolexecutor 8.5 ...
Volley默认是在UI线程返回响应,导致如果还需要对数据进行操作(如DB,筛选,排序等相对耗时任务),则需要另起Task(非UI线程)去做。问题,甚至踏入callback深渊。解决方案通过预测ExecutorService来让其成为单...
7.1 任务取消 7.2 停止基于线程的服务 7.3 处理反常的线程终止 7.4 jvm关闭 第8章 应用线程池 8.1 任务与执行策略问的隐性耦合 8.2 定制线程池的大小 8.3 配置threadpoolexecutor 8.4 扩展threadpoolexecutor 8.5 ...
:就是等待线程,到指定的等待时间才会往下执行,可以用 触发任务动态来取消等待。 8. 触发任务动态() .这个需要和等待任务动态一起用,也可以理解为 放弃等待中的任务 继续向下执行 9. 暂停() 暂停正在工作的线程...
4.9 在执行器中取消任务 151 4.10 在执行器中控制任务的完成 154 4.11 在执行器中分离任务的启动与结果的处理 158 4.12 处理在执行器中被拒绝的任务 164 第5章 Fork/Join框架 168 5.1 简介 168 ...
commondef.h 代码如下://单位秒,监测空闲列表时间间隔,在空闲队列中超过TASK_DESTROY_INTERVAL时间的任务将被自动...//线程池线程空闲自动退出时间间隔 ,5分钟const int THREAD_WAIT_TIME_OUT = 300; taskpool.cp
多线程leetcode 同步 更高级的同步原语。 实现了一些 Go 同步原语。 令牌 提供令牌实现。 只有拥有Token才能做事,然后才能将令牌移交给其他人。 批 提供批量实现。 类似于errgroup ,可以返回每个任务的所有错误...
任务取消 停止基于线程的服务 处理非正常的线程终止 JVM关闭 线程池的定制化使用 任务和执行策略之间的隐性耦合 线程池的大小 配置ThreadPoolExecutor(自定义的线程池) 此处需要注意...
来处理,这样把任务放入工作线程中执行,不会占用主线程的时间片,所以主线程会及时响应用户的操作,如果使用new Thread来执行任务,那么如果需要中途取消任务执行或者需要返回任务执行结果,就需要我们自己维护很多...