chapter7 取消与关闭1
来源:互联网 发布:php获取上上个文件夹名 编辑:程序博客网 时间:2024/06/08 00:33
java没有提供任何一种机制来安全的终止线程。但它提供了中断,这是一种协作机制,能够使一个线程终止另一个线程的当前工作。
这种协作机制是必要的,我们很少希望某个任务、线程或者服务立即停止,因为这种立即停止或使共享的数据结构处于不一致的状态。当需要停止时,应该首先清除当前正在执行的工作,然后再结束。
1、使用volatile来保存取消状态
@ThreadSafepublic class PrimeGenerator implements Runnable { private static ExecutorService exec = Executors.newCachedThreadPool(); @GuardedBy("this") 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); } static List<BigInteger> aSecondOfPrimes() throws InterruptedException { PrimeGenerator generator = new PrimeGenerator(); exec.execute(generator); try { SECONDS.sleep(1); } finally { generator.cancel(); } return generator.get(); }}
2、中断
在线程调用阻塞方法时,volatile变量的检查标志就可能无法被执行到,线程会一直阻塞,这种情况下,需要使用中断。
线程中断是一种协作机制,线程可以通过这种机制来通知另一个线程,告诉它在合适的或者可能的情况下停止当前的工作,并转而执行其他工作。
interrupt方法可以中断目标线程,isInterrupted方法可以获得线程的中断状态,静态interrupted方法可以清除当前线程的中断状态,并返回它之前的值。
阻塞库方法,例如sleep和wait等方法,都会检查线程何时中断,并在发现中断时提前返回。它们在响应中断时执行的操作包括:清除中断状态,抛出InterruptedException。JVM不能保证阻塞方法响应中断的速度,但在实际情况中,响应数据还是非常快的。
通常,中断是实现取消的最合理方式。
不能屏蔽InterruptedException,例如在catch块中捕获异常却不处理。除非代码中实现了线程的中断策略。
中断不会影响ThreadPoolExecutor线程池,中断一个线程之后,线程池会创建一个新的线程。
3、通过future来实现取消
future可以设置任务执行超时时间,如果超时则抛出异常,此时可以调用cancel方法来取消任务 。
public class TimedRun {
private static final ExecutorService taskExec = Executors.newCachedThreadPool(); public static void timedRun(Runnable r, long timeout, TimeUnit unit) throws InterruptedException { Future<?> task = taskExec.submit(r); try { task.get(timeout, unit); } catch (TimeoutException e) { // task will be cancelled below } catch (ExecutionException e) { // exception thrown in task; rethrow throw launderThrowable(e.getCause()); } finally { // Harmless if task already completed task.cancel(true); // interrupt if running } }}
4、不可中断的阻塞
并不是所有可阻塞方法都能响应中断:如果一个线程由于执行同步Socket I/O或者等待获得内置锁而阻塞,那么中断请求除了设置中断状态,没有其它任何作用。
这种情况下,可以通过改写interrupt方法将非标准的取消操作封装在Thread中。
public class ReaderThread extends Thread {
private static final int BUFSZ = 512; private final Socket socket; private final InputStream in; public ReaderThread(Socket socket) throws IOException { this.socket = socket; this.in = socket.getInputStream(); } public void interrupt() { try { socket.close(); } catch (IOException ignored) { } finally { super.interrupt(); } } public void run() { try { byte[] buf = new byte[BUFSZ]; while (true) { int count = in.read(buf); if (count < 0) break; else if (count > 0) processBuffer(buf, count); } } catch (IOException e) { /* Allow thread to exit */ } } public void processBuffer(byte[] buf, int count) { }}
- chapter7 取消与关闭1
- chapter7 取消与关闭2
- 取消与关闭
- 取消与关闭
- 取消与关闭
- java线程取消与关闭
- 并发的取消与关闭
- java线程取消与关闭
- 捕捉网页关闭与取消关闭事件
- chapter7 指针与引用
- java并发编程实战-取消与关闭1
- chapter7
- Java线程的取消与关闭
- Java 多线程 - 线程的取消与关闭
- java线程的取消与关闭
- 第7章 取消与关闭
- 多线程系列提高(8)--取消与关闭
- thinking in java test chapter7练习(1)~(10)组合与继承
- Java 目录重命名
- J2EE、J2SE、J2ME是什么意思?
- Android官网培训:管理位图内存
- Toward Good Thinking On Essential Questions(值得我们思考的一篇文章)
- 新的一天
- chapter7 取消与关闭1
- usb_host_dll
- 学习 严蔚敏讲数据结构笔记21
- 学习 严蔚敏讲数据结构笔记22
- 二维数组的动态分配及参数传递(转钱鑫)
- repo使用
- 学习 严蔚敏讲数据结构笔记23
- 学习 严蔚敏讲数据结构笔记24
- 学习 严蔚敏讲数据结构笔记25