转载自(https://blog.csdn.net/u013851082/article/details/69524861)
1、线程阻塞
一个线程进入阻塞状态可能的原因:
①通过调用sleep(millseconds)使任务进入休眠状态;
class Demo1 implements Runnable throws InterruptedException{
public void run(){
Thread.sleep(1000);
}
}
②通过调用wait()使线程挂起,直到线程获取notify()/notifyAll()消息,(或者在Java SE5中java.util.concurrent类库中等价的signal()/signalAll()消息),线程才会进入就绪状态;
class Demo2 implements Runnable{
public void run(){
Thread.await();
Thread.notify();
}
}
③任务在等待某个输入 / 输出流的完成;
class Demo3 implements Runnable throws InterruptedException{
private InputStream in;
public void run(){
in.read();
}
}
④任务试图在某个对象上调用其同步控制方法,但是对象锁不可用,因为另一个任务已经获取了该锁;
class Demo4 implements Runnable{
public synchronized void method1(){ }
public synchronized void method2(){ }
public void run(){
method1();
}
}
2、线程中断的方法
Thread类包含interrupt()方法,用于终止阻塞任务;
1)中断①②类线程休眠,挂起阻塞的方法
1.直接使用Thread.interrupt();
main(){
Thread t = new Thread(new Demo1());
t.interrupt();
}
2.使用Executor线程池,中断线程池中的所有线程;
main(){
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0;i<5;i++)
exec.execute(new Demo1())
exec.shutdownNow();
}
3.使用Executor线程池,中断线程池中单个阻塞的线程;
main(){
ExecutorService exec = Executors.newCachedThreadPool();
Futrue<?> f = exec.submit(new Demo1());
f.interrupt();
}
//中断后的清除代码放置在InterruptedException异常的catch捕获的代码块中
2)中断③类I/O阻塞的方法
使用Thread.iterrupt方法无法中断I/O阻塞,这对于基于Web的程序是很不利的;
①有一种解决方法:关闭任务在其上发生阻塞的底层资源;
main(){
ExecutorService exec = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(8080);
InputStream socketInput = new Socket("localhost",8080)
exec.execute(socketInput);
exec.execute(Sytsem.in);
//exec.shutdownNow(); 无法中断2个线程;
socketInput.close();
in.close();
exec.shutdownNow();
}
②java.nio类库提供了更加人性化的I/O中断,被阻塞的nio通道会自动地响应中断;
class Demo impelenets Runnable{
private final SocketChannel sc;
public Demo(SocketChannel sc){ this.sc = sc;}
public void run(){
try{
sc.read(ByteBuffer.allocate(1));
}catch(CloseByInteruptedException e1){
}catch(AsyncronousCloseException e2){
}catch(IOException e3){
}
}
}
public Test {
public static void main(){
ExecutorService exec = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(8080);
InetSocketAddress isa = new InetSocketAddress("localhost",8080);
SocketChannel sc1 = new SocketChannel.open(isa);
SocketChannel sc2 = new SocketChannel.open(isa);
exec.execute(new Demo(sc1));
Future<?> f = exec.submit(new Demo(sc2));
f.cancel(true); //可以终止sc1通道所在的线程;
exec.shutdownNow(); //可以终止exec线程池内所有的线程;
sc1.close();
sc2.close();
}
}
3)中断④类被互斥阻塞的线程
使用Thread.iterrupt方法无法中断互斥类线程,
解决方式1:可以使用ReentrantLock显式加锁,在JavaSE5中引入的新特性,ReentrantLock上阻塞的任务可以被中断;
class Task imlements Runnable{
private Lock lock = new ReentrantLock();
public void run(){
lock.lock();
try{
while(true)
}catch(InterruptedExcpetion e){
System.out.println("The Task is interrupted!");
}finally{
lock.unlock();
}
}
public void main(){
Thread t = new Thread(new Task());
t.start();
t.interrupt();
}
}
解决方式2:使用一个while(!Thread.interrupted())包裹同步的代码块
class Task impelments Runnable{
private synchronized void method1(){ }
public void run(){
try{
whlie(!Thread.interrupted())
method1();
}catch(InteruptedException e){
}
}
public static void main(){
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Task());
exec.shutdownNow(); //线程被打断
/*或 Thread t = new Thread(new Task());
t.start();
t.interrupt(); */
}
}
分享到:
相关推荐
线程控制是Java多线程编程中的重要概念,包括中断、挂起、恢复和停止。本实例将深入探讨这些主题,帮助你更好地理解和掌握Java中线程的高级操作。 1. **线程中断**: Java通过`Thread.interrupt()`方法提供线程...
在Java多线程编程中,LockSupport类是一个重要的工具,它提供了一种低级别的线程阻塞和唤醒机制。LockSupport并不像synchronized或java.util.concurrent.locks包中的Lock接口那样提供锁的完整功能,但它提供了两个...
如果线程正在阻塞(如等待I/O或者在`wait()`, `sleep()`, `join()`等方法中),`interrupt()`会抛出`InterruptedException`,从而让线程有机会从阻塞状态恢复并结束。在线程的业务逻辑中,应定期检查`isInterrupted...
5. **中断机制**:Java中的`Thread.interrupt()`方法可以设置线程的中断标志,处于阻塞状态(如等待I/O或持有锁)的线程在检测到中断时会抛出`InterruptedException`,从而有机会优雅退出。对于休眠的线程,`Thread....
4. **线程的Interrupt方法**:虽然不能直接暂停线程,但可以中断正在阻塞的线程,然后在线程的异常处理程序中进行恢复逻辑。 5. **线程池和Task类**:使用线程池或`Task`(异步编程模型的一部分)可以更方便地管理...
熔断降级组件需要在指定的超时时间内中断请求线程,以避免请求长时间阻塞系统资源。在这篇文章中,我们将介绍如何在 Java 中实现线程的超时中断。 实现超时中断的思路: 1. 使用 Thread.interrupt() 方法设置线程...
ISR通常在中断发生时立即执行,负责快速保存现场,处理紧急事件,然后恢复现场并退出,以避免长时间阻塞其他进程。中断底半部则用于执行那些非原子性、耗时的操作,它可以在ISR执行后稍后异步执行。 ARM架构中断...
5. 中断处理的安全性:在中断处理程序中修改全局变量需要特别小心,因为它可能在多线程环境中造成竞态条件。 6. 驱动兼容性:不同的硬件可能使用不同的中断处理方式,因此在编写跨平台的代码时需要考虑到这一点。 ...
总之,Java中的线程中断是一种协调和控制并发执行的重要机制,它提供了安全地终止线程或改变线程执行路径的方式,尤其是在处理阻塞操作时。理解和熟练使用中断机制,对于编写高效、可靠的并发代码至关重要。
8. **中断处理中的同步问题**:在多线程环境中,中断处理可能需要考虑与其他线程间的同步,以防止数据竞争和其他并发问题。 实验中的代码应该涵盖了这些概念,并通过实例展示了如何配置中断控制器、编写ISR、处理...
1. `interrupt()`:用于设置线程的中断标志位,如果线程正在阻塞(如等待 I/O 或调用 `sleep()`、`wait()` 等),则会抛出 `InterruptedException`,使线程从阻塞状态恢复并清除中断标志。 2. `isInterrupted()`:...
在Java中,`resume()`方法已被弃用,取而代之的是使用中断机制(`interrupt()`)或者使用`join()`方法来控制线程的恢复。在C++中,可以使用`pthread_continue()`来恢复线程,但这同样需要操作系统级别的支持。 为了...
在计算机系统中,信号(Signal)是一种轻量级的、非阻塞的进程间通信方式,它允许操作系统向进程发送通知,告知进程发生了某种特定事件,如资源请求、异常条件或者用户交互。 信号产生的主要方式有两种:硬件中断和...
STM32F103CB支持多种类型的外部中断,包括线程模式和中断模式,以及上升沿、下降沿和双沿触发等。这些特性使得它能够灵活地处理各种输入信号,比如按钮的按下和释放。 在外部中断的应用中,首先需要配置GPIO端口...
工作队列是由一组内核线程(中断守护线程)驱动的,这样即使有长时间的任务,也不会阻塞其他中断的处理。 **声明和使用小任务**: 在Linux中,开发者可以使用`DECLARE_TASKLET`宏声明一个小任务,并指定处理函数。...
处理完毕后,系统会恢复到中断发生前的状态继续执行原任务。在这个过程中,ISR扮演着至关重要的角色。 ### 一、为什么中断服务程序不能睡眠? #### 1.1 中断与ISR的关系 中断是硬件层面的概念,而ISR是软件层面的...
- ISR完成对中断事件的处理后,会恢复被中断程序的上下文,并返回到被中断的地方继续执行。 3. **中断向量表**: - Windows操作系统维护了一个中断向量表(Interrupt Vector Table, IVT),其中每个条目都包含一...
这意味着当一个线程阻塞(如等待I/O操作)时,程序需要决定哪个线程应该获得CPU资源。在单个CPU上,这通常意味着在可运行的线程之间切换。在多核系统中,每个核心可以并发地运行不同线程,进一步提高了并行性。 在...
本文将详细介绍如何通过插入异常来实现线程的干净终止,并讨论防止线程阻塞的策略。 首先,让我们来看看如何通过插入异常来终止线程。这种方法通常涉及以下步骤: 1. 暂停目标线程:使用操作系统提供的API(例如...
软中断作为进程间通信的一种手段,其主要优势在于可以异步地通知其他进程,而不会阻塞当前执行的进程。在Linux系统中,软中断通常由软件指令触发,如发送I/O完成信号。通过注册中断处理程序,当软中断发生时,操作...