- 浏览: 187871 次
- 性别:
- 来自: 杭州
博客专栏
-
Java技术分享
浏览量:0
文章分类
最新评论
-
masuweng:
学习了,学习了
mybatis是如何防止SQL注入的 -
somefuture:
终于知道了#$的区别
mybatis是如何防止SQL注入的 -
masuweng:
...
tomct处理请求的流程 -
zhp8341:
masuweng 写道寻求cas的更多例子, http://w ...
JUC之CAS -
臻是二哥:
java.util.concurrent包中到处都使用了CAS ...
JUC之CAS
中断处理
在java程序中,当使用Thread.sleep()或者BlockingQueue.take()等阻塞方法时,需要处理InterruptedException。对于这种异常,通常有2种方案进行处理。
1. 传递异常:将异常传递给方法的调用者。示例如下:
2. 恢复异常:在大多数情况下,异常是可以传递的,但有些情况是无法传递异常的,比如在Runnable的run()方法中,我们不可以抛出异常。此时需要我们恢复异常,这样在调用栈中更高层次的代码将看到引发了一个中断。示例如下:
以上是处理InterruptedException的常用方法,对于InterruptedException,千万不要捕获异常但不做任何处理。当我们使用中断来结束线程时,在catch块中也可以使用interrupted()来清除异常。
任务取消
多线程编程时,有时候需要取消某些任务线程,有以下3种方案:
1. 设定一个线程取消的标记,任务线程定期的检查这个标记。示例如下:
当while(!cancel)循环中调用了一个阻塞的方法时,使用标记位的方式终止程序就不再使用了,此时使用中断的方式退出程序:
3. 在生产者消费者问题中,使用“毒丸对象”来终止消费者线程。
在java程序中,当使用Thread.sleep()或者BlockingQueue.take()等阻塞方法时,需要处理InterruptedException。对于这种异常,通常有2种方案进行处理。
1. 传递异常:将异常传递给方法的调用者。示例如下:
BlockingQueue<String> queue; public String getNextString() throws InterruptedException{ return queue.take(); }
2. 恢复异常:在大多数情况下,异常是可以传递的,但有些情况是无法传递异常的,比如在Runnable的run()方法中,我们不可以抛出异常。此时需要我们恢复异常,这样在调用栈中更高层次的代码将看到引发了一个中断。示例如下:
BlockingQueue<String> queue; public String getNextString() throws InterruptedException{ String result=null; try{ result=queue.take(); }catch(InterruptedException e){ Thead.currentThread.interrupt(); }finally{ Return result; } }
以上是处理InterruptedException的常用方法,对于InterruptedException,千万不要捕获异常但不做任何处理。当我们使用中断来结束线程时,在catch块中也可以使用interrupted()来清除异常。
任务取消
多线程编程时,有时候需要取消某些任务线程,有以下3种方案:
1. 设定一个线程取消的标记,任务线程定期的检查这个标记。示例如下:
class Task implements Runnable{ private volatile boolean cancel=false; @Override public void run() { while(!cancel){ System.out.println("..."); } } public void cancel(){ cancel=true; } }2. 上面的示例描述的是最一般的场景,试想一下,如果while(!cancel)循环中调用了一个阻塞的方法,那么有这样一种可能:程序可能阻塞在某个方法中。示例如下:
class Task implements Runnable{ private volatile boolean cancel=false; private BlockingQueue<String> blockingQueue; public Task(BlockingQueue<String> queue){ this.blockingQueue=queue; } @Override public void run() { try{ while(!cancel){ System.out.println("..."); this.blockingQueue.take();//当程序阻塞在此处时,即便cancel被更新了,也无法感知,这种情况下,程序永远无法退出。 } }catch(InterruptedException e){ Thread.currentThread().interrupt(); } } public void cancel(){ cancel=true; } }
当while(!cancel)循环中调用了一个阻塞的方法时,使用标记位的方式终止程序就不再使用了,此时使用中断的方式退出程序:
import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class CDemo { public static void main(String [] args) throws Exception{ BlockingQueue<String> b=new ArrayBlockingQueue<String>(3); b.put("a"); b.put("ab"); b.put("abc"); Task task=new Task(b); task.start(); Thread.sleep(4000); task.cancel(); } } class Task extends Thread{ private BlockingQueue<String> blockingQueue; public Task(BlockingQueue<String> queue){ this.blockingQueue=queue; } @Override public void run() { try{ while(true){ // if(Thread.currentThread().isInterrupted()) //一定注意,这行是错误做法 if(interrupted())//判断当前线程是否被中断 break; String str=this.blockingQueue.take(); System.out.println(str); } }catch(InterruptedException e){ //Thread.currentThread().interrupt(); interrupted();//清除中断痕迹 }finally{ System.out.println("线程结束!"); } } public void cancel(){ this.interrupt();//中断当前线程 // Thread.currentThread().interrupt(); //一定注意,这行是错误做法 } }
3. 在生产者消费者问题中,使用“毒丸对象”来终止消费者线程。
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; public class Coordinator { public static final Object POISON_PILL = new Object();//special object to kill consumers private int productCount = 1; private int consumerCount = 3; public void startAll() throws Exception{ BlockingQueue<Object> queue = new ArrayBlockingQueue<Object>(5); CountDownLatch activeProductorNum = new CountDownLatch(productCount); CountDownLatch activeConsumerNum = new CountDownLatch(consumerCount); for(int i = 0; i < consumerCount; i++){ new Thread(new Consumer("consumer " + i, queue,activeConsumerNum)).start(); } for(int i = 0; i < productCount; i++){ new Thread(new Producer("producer " + i, queue, activeProductorNum)).start(); } activeProductorNum.await();//等待所有生产者生产结束 System.out.println("All producer finished, putting POISON_PILL to the queue to stop consumers!"); queue.put(POISON_PILL); activeConsumerNum.await();//等待所有生产者生产结束 System.out.println("All consumer finished!"); } public static void main(String[] args) throws Exception{ new Coordinator().startAll(); } } class Producer implements Runnable { private String name; private BlockingQueue<Object> queue; private CountDownLatch activeProducerNum; public Producer(String name, BlockingQueue<Object> queue, CountDownLatch activeProducerNum){ this.name = name; this.queue = queue; this.activeProducerNum=activeProducerNum; } @Override public void run() { try { for(int i=0;i<10;i++){ queue.put(i); System.out.println(name + " produced "+i); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally{ System.out.println(name + " finished."); activeProducerNum.countDown(); } } } class Consumer implements Runnable { private String name; private BlockingQueue<Object> queue; private CountDownLatch activeConsumerNum; public Consumer(String name, BlockingQueue<Object> queue,CountDownLatch activeConsumerNum){ this.name = name; this.queue = queue; this.activeConsumerNum=activeConsumerNum; } @Override public void run() { try { while (true) { Object item = queue.take(); if (item == Coordinator.POISON_PILL) { queue.put(item);//放回继续毒害其他消费者 break; } System.out.println(name + " consumed "+item); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally{ System.out.println(name + " finished"); activeConsumerNum.countDown(); } } }
发表评论
-
精心准备的讲解Java多线程的知乎Live
2018-09-02 21:39 704花了一个月的时间,结合自己的理解,制作了一个以图片的方式讲解J ... -
在知乎推出Java求职类专栏文章
2018-08-27 12:06 790从昨天起,笔者开始在知乎推出Java求职类专栏文章,主要涉及一 ... -
JUC之AQS
2016-07-27 15:49 1267AQS是同步框架,它进行 ... -
JUC之CAS
2016-07-27 10:56 1643JUC是java.util.concurrent包 ... -
JAVA并发-线程状态和线程组
2016-07-18 14:14 1315在Java中,线程有6种基本状态,理解这6种基本状态之间的关系 ... -
JAVA并发-条件队列
2016-07-02 09:57 1115在JVM系列博客http://yizhen ... -
JAVA并发-显式锁(二)
2016-06-06 09:25 1024在上一篇博客《JAVA并发-显式锁(一)》中介绍了Lock和R ... -
JAVA并发-显式锁(一)
2016-06-05 20:40 891JAVA语言除了提供内置锁synchronized,还在JDK ... -
JAVA并发-减少锁的竞争
2016-06-04 16:01 1898降低锁的竞争可以提高 ... -
JAVA并发-3种典型的死锁
2016-06-03 19:54 1621在JAVA并发编程中,我们 ... -
JAVA并发-3种典型的死锁
2016-06-03 10:02 10在JAVA并发编程中,我们 ... -
JAVA并发-ThreadPoolExecutor线程池的使用
2016-05-30 16:19 2356在博客JAVA并发-Executor任务执行框架中曾说过,Ex ... -
JAVA并发-Executor任务执行框架
2016-05-27 19:10 432首先介绍两个重要的接 ... -
JAVA并发-DCL与JMM
2016-04-26 19:21 1608首先必须声明,在volatil ... -
JAVA并发- 典型连接池的实现
2016-04-22 10:44 1210package com.xyz.connpool; pu ... -
JAVA并发-构建可靠的结果缓存
2016-04-10 16:58 55在学习了前面关于多线程的博客之后,下面来介绍一个构建可靠结果缓 ... -
JAVA并发-并发编程常用类
2016-04-08 11:07 991在讲同步工具类之前,笔者想先介绍一下Runnable,Call ... -
JAVA并发-同步容器和并发容器
2016-04-07 19:02 698常见的同步容器类包括V ... -
JAVA并发-开发线程安全类
2016-04-01 10:23 840我们知道,面向对象的 ... -
JAVA并发-为现有的线程安全类添加原子方法
2016-03-30 20:46 1435JAVA中有许多线程安全的基础模块类,一般情况下,这些基础模块 ...
相关推荐
在Java并发编程中,线程的关闭和取消是一项重要的任务,因为不正确的处理可能导致数据不一致、资源泄漏等问题。在Java中,强制停止线程并不是一个推荐的做法,因为这可能会导致系统状态的不稳定。传统的`Thread.stop...
1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全...
Java并发编程是Java开发者必须掌握的关键技能之一,它涉及到如何在多线程环境中高效、安全地执行程序。并发编程能够充分利用多核处理器的...总的来说,Java并发编程是一门深奥的学问,需要不断学习和实践才能真正精通。
"java并发编程-构建块"这个主题涵盖了使程序能够同时处理多个任务的关键概念和技术。在这个主题下,我们将深入探讨Java中用于构建高效并发应用的核心工具和概念。 1. **线程**:Java中的线程是并发编程的基础,每个...
Java并发程序设计是Java编程技术中一个重要的领域,它涉及如何在多线程环境下编写有效且安全的代码。本文将从以下几个方面详细讲解Java并发程序设计的核心知识点: 1. 使用线程的经验:线程是并发程序的基础,包括...
Java并发框架是Java JDK中内置的一系列用于处理多线程并行执行的工具和类库,自JDK 5.0引入以来,极大地简化了并发编程的复杂性。这个框架由Doug Lea设计,并在JSR-166任务中提出,最终在Tiger(JDK 5)版本中被引入...
- **Future和ExecutorService**:`ExecutorService`提供线程池管理,`Future`接口表示异步计算的结果,可以检查计算是否完成,获取结果或取消任务。 - **CountDownLatch/CyclicBarrier/Semaphore**:这些是协调多...
7.1 任务取消 7.2 停止基于线程的服务 7.3 处理反常的线程终止 7.4 JVM关闭 第8章 应用线程池 8.1 任务与执行策略问的隐性耦合 8.2 定制线程池的大小 8.3 配置ThreadPoolExecutor 8.4 扩展ThreadPoolExecutor 8.5 ...
《Java并发编程 设计原则与模式 第二版》是一本广受赞誉的经典书籍...通过阅读本书,开发者可以深入了解Java并发编程的核心概念,学习如何有效利用并发工具和设计模式解决实际问题,从而提升多线程应用的稳定性和性能。
1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 性能问题 1.4 线程无处不在 第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全...
7.1 任务取消 7.2 停止基于线程的服务 7.3 处理反常的线程终止 7.4 jvm关闭 第8章 应用线程池 8.1 任务与执行策略问的隐性耦合 8.2 定制线程池的大小 8.3 配置threadpoolexecutor 8.4 扩展threadpoolexecutor 8.5 ...
任务取消 停止基于线程的服务 处理非正常的线程终止 JVM关闭 线程池的定制化使用 任务和执行策略之间的隐性耦合 线程池的大小 配置ThreadPoolExecutor(自定义的线程池) 此处需要注意...
通过解答复习题,检验和巩固所学知识,确保对Java并发编程的核心概念和技术有深刻的理解和应用能力。 #### 总结 Java并发编程涉及多个层次的知识点,从基础的线程管理到高级的无锁编程,再到并行计算理论,构成了...
Java并发编程是Java开发中的重要领域,特别是在大型分布式系统和多线程应用中不可或缺。"java并发.rar"这个压缩包可能包含了一些关于Java并发编程的课程资料和学习资源,旨在帮助开发者深入理解并掌握这一技术。 ...
Java并发编程中的线程中断是一个关键机制,它允许开发者在程序运行过程中显式地请求某个线程停止执行。在本示例中,我们创建了一个名为`PrimeGenerator`的线程,该线程会不断地查找并打印质数。线程中断机制的使用...
### Java并发程序设计知识点详解 #### 一、使用线程的经验 在Java中,线程是并发编程的基础单元。为了更好地管理和识别线程,给线程命名是非常重要的实践。 1. **设置名称**: - **重要性**:命名线程可以帮助...