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到最后一个的时候,该线程才会退出。
分享到:
相关推荐
│ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括同步容器类、并发容器类、阻塞队列和生产者消费者模式、阻塞和中断方法、同步工具类。最后是构建高效且可伸缩的结果缓存
Java并发编程是Java开发中的重要领域,它涉及到多线程、同步、锁机制、线程池等关键概念,是提高程序性能和效率的关键技术。在Java中,并发编程的运用可以充分利用多核处理器的能力,实现高效的多任务处理。以下是对...
Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...
《Java并发编程实践》这本书是Java开发者深入理解并发编程的重要参考。以下是对书中关键知识点的总结: 1. **线程和进程的区别** - **线程**:是程序执行的最小单位,一个进程中可以有多个线程,它们共享同一块...
### Java并发编程笔记 #### 一、线程与进程 - **进程**: 是操作系统资源分配的基本单位,每个进程都有自己的独立内存空间。例如,当我们打开QQ或者音乐播放器时,实际上是在启动`qq.exe`或`Music.exe`这样的程序,...
JAVA并发编程实践-构建执行程序块-学习笔记 JAVA并发编程实践是指在JAVA编程语言中,使用多线程、并发编程来实现高效、可靠的程序执行。构建执行程序块是指在并发编程中,使用线程安全的类来管理状态,以确保程序的...
在Java并发编程中,线程的关闭和取消是一项重要的任务,因为不正确的处理可能导致数据不一致、资源泄漏等问题。在Java中,强制停止线程并不是一个推荐的做法,因为这可能会导致系统状态的不稳定。传统的`Thread.stop...
首先,"并发编程之深入理解JMM&并发三大特性",这里的JMM指的是Java内存模型(Java Memory Model),它是Java平台中的核心概念,用于规定了线程之间如何共享和访问内存中的数据。并发的三大特性包括原子性、可见性和...
这篇“Java线程编程学习笔记(二)”很可能是对Java并发编程深入探讨的一部分,特别是涉及多线程示例的实践应用。我们将从标题、描述以及标签来推测可能涵盖的知识点,并结合"Multi-Threads Demo"这一压缩包文件名来...
首先,"Java并发编程笔记"这部分内容可能涵盖了以下几个关键知识点: 1. **线程基础**:线程的创建、启动、中断和销毁,以及如何使用`Thread`类和`Runnable`接口来创建线程。 2. **并发控制**:包括`synchronized`...
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
通过阅读`多线程笔记.doc`和运行`threadDemo`示例代码,你可以对Java多线程有更深入的理解,并能够在实际项目中灵活运用这些知识,解决并发问题。同时,博客地址提供了更多详细内容,可以帮助你进一步探索和实践。
9. **线程中断**:通过Thread.interrupt()方法可以请求中断一个线程,线程在运行过程中应定期检查中断标志,以便优雅地结束运行。 10. **线程间的通信**:Java的BlockingQueue接口和相关的类(如ArrayBlockingQueue...