`
cyril0513
  • 浏览: 15770 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

<<java并发编程>>读书笔记之线程中断

阅读更多
public class PrimeGenerator implements Runnable {

	private final List<BigInteger> list = new ArrayList<BigInteger>();

	private volatile boolean cancell;

	@Override
	public void run() {
		BigInteger big = BigInteger.ONE;
		while (!cancell) {
			big = big.nextProbablePrime();
			synchronized (list) {
				list.add(big);
			}
		}
	}

	public List<BigInteger> get() {
		synchronized (list) {
			return new ArrayList<BigInteger>(list);
		}
	}

	public void setCancell(boolean cancell) {
		this.cancell = cancell;
	}

	public List<BigInteger> aSecondOfPrimer(PrimeGenerator p) throws Exception {
		new Thread(p).start();
		try {
			Thread.sleep(10);
		} finally {
			this.setCancell(true);
		}
		return p.get();

	}

	public static void main(String[] args) throws Exception {
		PrimeGenerator p = new PrimeGenerator();
		System.out.println(p.aSecondOfPrimer(p));

	}

}


最简单的中断方式,使用一个volatile的boolean变量,控制终止。但是不一定signal后就会马上终止,可能在在执行run的一些代码的时候,会出现延迟,甚至会出错。
不过我们把signal放在finally块中,保证一定会执行。
有的时候,这种方式不一定就是安全的,例如有一些类自身就有阻塞的行为,例如BlockingQueue类型,从以下代码可以看出:
package com.test.db;

import java.math.BigInteger;
import java.util.concurrent.BlockingQueue;

public class BlockTest implements Runnable {

	private final BlockingQueue<BigInteger> queue = new ArrayBlockingQueue<BigInteger>(
			1);
	private volatile boolean cancell;

	// 生产者线程
	@Override
	public void run() {
		BigInteger big = BigInteger.ONE;
		while (!cancell) {
			try {
				queue.put(big=big.nextProbablePrime());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void setInterrupted() {
		cancell = true;
	}

	public void consumer(BlockTest b) {
		new Thread(b).start();
		try {
			while (true)
				try {
					System.out.println(queue.take());
					//System.out.println("size :"+queue.size());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
		} finally {
			b.setInterrupted();
		}

	}

	public static void main(String[] args) {
		BlockTest b = new BlockTest();
		b.consumer(b);
	}

}


为什么说这是unreliable,我们可以看一下ArrayBlockingQueue的源代码,先看一下put
 public void put(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        final E[] items = this.items;
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            try {
              while (count == items.length)
                    notFull.await();          
             } catch (InterruptedException ie) {
                notFull.signal(); // propagate to non-interrupted thread
                throw ie;
            }
            insert(e);
        } finally {
            lock.unlock();
        }
    }

我们指定的capacity的是1,也就是当count和items.length相等的时候,这个queue会被阻塞。
问题就在于:当生产者线程的put>take,这个时候queue会被很快填满.此时如果take速度比较慢,并且signal中断,这个时候是没有办法停止的,除非当take到最后一个的时候,该线程才会退出。
分享到:
评论

相关推荐

    汪文君高并发编程实战视频资源下载.txt

    │ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...

    《java并发编程实战》读书笔记-第5章-基础构建模块

    《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括同步容器类、并发容器类、阻塞队列和生产者消费者模式、阻塞和中断方法、同步工具类。最后是构建高效且可伸缩的结果缓存

    Java并发编程学习笔记.

    Java并发编程是Java开发中的重要领域,它涉及到多线程、同步、锁机制、线程池等关键概念,是提高程序性能和效率的关键技术。在Java中,并发编程的运用可以充分利用多核处理器的能力,实现高效的多任务处理。以下是对...

    Java并发编程(学习笔记).xmind

    Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...

    [原]Java并发编程实践-读书笔记

    《Java并发编程实践》这本书是Java开发者深入理解并发编程的重要参考。以下是对书中关键知识点的总结: 1. **线程和进程的区别** - **线程**:是程序执行的最小单位,一个进程中可以有多个线程,它们共享同一块...

    java并发编程笔记

    ### Java并发编程笔记 #### 一、线程与进程 - **进程**: 是操作系统资源分配的基本单位,每个进程都有自己的独立内存空间。例如,当我们打开QQ或者音乐播放器时,实际上是在启动`qq.exe`或`Music.exe`这样的程序,...

    JAVA并发编程实践-构建执行程序块-学习笔记

    JAVA并发编程实践-构建执行程序块-学习笔记 JAVA并发编程实践是指在JAVA编程语言中,使用多线程、并发编程来实现高效、可靠的程序执行。构建执行程序块是指在并发编程中,使用线程安全的类来管理状态,以确保程序的...

    JAVA并发编程实践-线程的关闭与取消-学习笔记

    在Java并发编程中,线程的关闭和取消是一项重要的任务,因为不正确的处理可能导致数据不一致、资源泄漏等问题。在Java中,强制停止线程并不是一个推荐的做法,因为这可能会导致系统状态的不稳定。传统的`Thread.stop...

    并发编程之一 日常学习笔记

    首先,"并发编程之深入理解JMM&并发三大特性",这里的JMM指的是Java内存模型(Java Memory Model),它是Java平台中的核心概念,用于规定了线程之间如何共享和访问内存中的数据。并发的三大特性包括原子性、可见性和...

    Java线程编程学习笔记(二)

    这篇“Java线程编程学习笔记(二)”很可能是对Java并发编程深入探讨的一部分,特别是涉及多线程示例的实践应用。我们将从标题、描述以及标签来推测可能涵盖的知识点,并结合"Multi-Threads Demo"这一压缩包文件名来...

    java多线程编程笔记

    【Java多线程编程笔记】 Java 多线程编程是Java开发中不可或缺的一部分,它允许程序同时执行多个任务,提高程序的效率和响应性。在深入理解Java多线程之前,我们首先要理解操作系统中的基本概念——进程和线程。 1...

    Java学习资料-并发编程.zip

    首先,"Java并发编程笔记"这部分内容可能涵盖了以下几个关键知识点: 1. **线程基础**:线程的创建、启动、中断和销毁,以及如何使用`Thread`类和`Runnable`接口来创建线程。 2. **并发控制**:包括`synchronized`...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载4.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载2.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载3.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    Java互联网架构多线程并发编程原理及实战 视频教程 下载1.zip

    Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....

    java多线程笔记全手打

    通过阅读`多线程笔记.doc`和运行`threadDemo`示例代码,你可以对Java多线程有更深入的理解,并能够在实际项目中灵活运用这些知识,解决并发问题。同时,博客地址提供了更多详细内容,可以帮助你进一步探索和实践。

    马士兵多线程笔记.zip

    9. **线程中断**:通过Thread.interrupt()方法可以请求中断一个线程,线程在运行过程中应定期检查中断标志,以便优雅地结束运行。 10. **线程间的通信**:Java的BlockingQueue接口和相关的类(如ArrayBlockingQueue...

Global site tag (gtag.js) - Google Analytics