Java 7之多线程
来源:互联网 发布:淘宝300解id锁是可靠吗 编辑:程序博客网 时间:2024/05/01 12:23
Java没有一种安全的抢占式方法来停止线程,只有一些协作式机制。其中一种协作机制能设置某个“已请求取消”标志,而任务将定期查看该标志。如果设置了这个标志,那么任务将提前结束。举例如下:
- public class PrimeGenerator implements Runnable {
- private static ExecutorService exec = Executors.newCachedThreadPool();
- private final List<BigInteger> primes = new ArrayList<BigInteger>();
- private volatile boolean cancelled; // 为了保证可靠,需要volatile类型
- public void run() {
- BigInteger p = BigInteger.ONE;// 创建一个大整数类型,初始值为1
- while (!cancelled) {
- p = p.nextProbablePrime();
- synchronized (this) { // 在添加时要确保同步
- primes.add(p);
- }
- }
- }
- // 设置取消任务的标识cancelled,以防止搜索素数的线程永远执行下去
- public void cancel() {
- cancelled = true;
- }
- // 获取已经计算出来的素数
- public synchronized List<BigInteger> get() { // 对ArrayList进行复制,保证正确的遍历
- 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(); // 确保在调用sleep时被中断也能取消素数生成器的任务
- }
- return generator.get();
- }
- }
如果使用这种策略来请求取消,那么当任务调用了一个阻塞方法的时候,可能任何永远不会检查取消标志,因此永远不会结束。如下举例:
- class BrokenPrimeProducer extends Thread {
- private final BlockingQueue<BigInteger> queue; // 阻塞队列
- private volatile boolean cancelled = false;
- BrokenPrimeProducer(BlockingQueue<BigInteger> queue) {
- this.queue = queue;
- }
- public void run() {
- try {
- BigInteger p = BigInteger.ONE;
- while (!cancelled)
- queue.put(p = p.nextProbablePrime());
- } catch (InterruptedException consumed) {
- }
- }
- public void cancel() {
- cancelled = true;
- }
- }
线程中断是一种协作机制,每个线程都有一个boolean类型的中断状态。在Thread类中提供了3个中断方法,如下:
- public void interrupt(); // 中断目标线程
- public boolean isInterrupted(); // 返回目标线程的中断状态
- public static boolean interrupted();// 清除当前线程的中断状态,并返回它之前的值。也是清除中断状态的唯一方法
(1)interrupt()方法
对于阻塞库方法,如wait、join、sleep方法,都会检查线程何时中断,并且在发现中断时提前返回。调用这个方法会引起这个线程的interrupt状态被清空(设为false),并且会抛出InterruptedException,表示阻塞操作由于中断而提前结束。
当线程在非阻塞状态下中断时,中断状态将被设置。
(2)isInterrupted()方法
这个方法的源代码如下:
- public boolean isInterrupted() {
- return isInterrupted(false);
- }
- private native boolean isInterrupted(boolean ClearInterrupted);
(3)interrupted()方法
来看这个方法的源代码,如下:
- public static boolean interrupted() {
- return currentThread().isInterrupted(true);
- }
- private native boolean isInterrupted(boolean ClearInterrupted);
注意:这个是个静态方法,并且返回的是当前线程状态,并不一定是调用者的线程状态。
使用这几个方法可以解决如上的自定义取消机制与可阻塞的库函数之间交互的问题,如下:
- public class PrimeProducer extends Thread {
- private final BlockingQueue<BigInteger> queue;
- PrimeProducer(BlockingQueue<BigInteger> queue) {
- this.queue = queue;
- }
- public void run() {
- try {
- BigInteger p = BigInteger.ONE;
- while (!Thread.currentThread().isInterrupted())// 在在启动寻找素数前进行检测
- queue.put(p = p.nextProbablePrime());
- } catch (InterruptedException consumed) {
- /* Allow thread to exit */
- }
- }
- public void cancel() {
- interrupt();
- }
- }
转载自http://blog.csdn.net/mazhimazh/
0 0
- Java 7之多线程
- Java 7之多线程
- Java 7之多线程- CountDownLatch
- Java 7之多线程线程池
- Java 7之多线程线程池
- Java 7之多线程线程池
- 【Java】Java之多线程
- Java 7之多线程第7篇
- Java 7之多线程并发容器 - CopyOnWriteArrayList
- Java 7之多线程并发容器 - ConcurrentHashMap
- Java 7之多线程并发容器 - ArrayBlockingQueue
- Java 7之多线程并发容器 - LinkedBlockingQueue
- Java 7之多线程并发容器
- Java 7之多线程并发容器
- Java 7之多线程并发容器
- Java 7之多线程并发容器
- Java 7之多线程第12篇
- Java 7之多线程第11篇
- 分治法-leetcode
- find & rm 组合删除目录
- jzoj 4999. 【NOI2017模拟3.3】螺旋序列 不删除版莫队算法
- 如何强制360浏览器以极速模式打开页面(lofter博客转移飞碟)
- c# 无法加载DLL“xxxx”:找不到指定的模块(异常来自HRESULT:0X8007007E)的一个解决方法
- Java 7之多线程
- 工具推荐:LICEcap-录屏为动态图片
- Dialog自定义setView点击事件空指针
- C++类中的数据成员能否在定义类的时候就初始化?
- 解决win7下Allegro中光标由小十字改为满屏十字后出现残影的问题
- 通过gradle下载jar包
- StampedLock的使用
- 链表
- ehcache memcache redis 缓存