`
水煮青蛙
  • 浏览: 2235 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
社区版块
存档分类
最新评论

线程阻塞中断的恢复方式

 
阅读更多
转载自(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(); */
     }
}
分享到:
评论

相关推荐

    JAVA100例之实例66 实现对线程的控制,中断、挂起、恢复、停止

    线程控制是Java多线程编程中的重要概念,包括中断、挂起、恢复和停止。本实例将深入探讨这些主题,帮助你更好地理解和掌握Java中线程的高级操作。 1. **线程中断**: Java通过`Thread.interrupt()`方法提供线程...

    详解Java多线程编程中LockSupport类的线程阻塞用法

    在Java多线程编程中,LockSupport类是一个重要的工具,它提供了一种低级别的线程阻塞和唤醒机制。LockSupport并不像synchronized或java.util.concurrent.locks包中的Lock接口那样提供锁的完整功能,但它提供了两个...

    JAVA多线程之中断机制stop()、interrupted()、isInterrupted()

    如果线程正在阻塞(如等待I/O或者在`wait()`, `sleep()`, `join()`等方法中),`interrupt()`会抛出`InterruptedException`,从而让线程有机会从阻塞状态恢复并结束。在线程的业务逻辑中,应定期检查`isInterrupted...

    唤醒阻塞休眠线程示例

    5. **中断机制**:Java中的`Thread.interrupt()`方法可以设置线程的中断标志,处于阻塞状态(如等待I/O或持有锁)的线程在检测到中断时会抛出`InterruptedException`,从而有机会优雅退出。对于休眠的线程,`Thread....

    多线程窗口暂停线程 并恢复

    4. **线程的Interrupt方法**:虽然不能直接暂停线程,但可以中断正在阻塞的线程,然后在线程的异常处理程序中进行恢复逻辑。 5. **线程池和Task类**:使用线程池或`Task`(异步编程模型的一部分)可以更方便地管理...

    Java中实现线程的超时中断方法实例

    熔断降级组件需要在指定的超时时间内中断请求线程,以避免请求长时间阻塞系统资源。在这篇文章中,我们将介绍如何在 Java 中实现线程的超时中断。 实现超时中断的思路: 1. 使用 Thread.interrupt() 方法设置线程...

    linux中断.rar

    ISR通常在中断发生时立即执行,负责快速保存现场,处理紧急事件,然后恢复现场并退出,以避免长时间阻塞其他进程。中断底半部则用于执行那些非原子性、耗时的操作,它可以在ISR执行后稍后异步执行。 ARM架构中断...

    c++中断及遇到的问题

    5. 中断处理的安全性:在中断处理程序中修改全局变量需要特别小心,因为它可能在多线程环境中造成竞态条件。 6. 驱动兼容性:不同的硬件可能使用不同的中断处理方式,因此在编写跨平台的代码时需要考虑到这一点。 ...

    java多线程1

    总之,Java中的线程中断是一种协调和控制并发执行的重要机制,它提供了安全地终止线程或改变线程执行路径的方式,尤其是在处理阻塞操作时。理解和熟练使用中断机制,对于编写高效、可靠的并发代码至关重要。

    中断实验—Arm

    8. **中断处理中的同步问题**:在多线程环境中,中断处理可能需要考虑与其他线程间的同步,以防止数据竞争和其他并发问题。 实验中的代码应该涵盖了这些概念,并通过实例展示了如何配置中断控制器、编写ISR、处理...

    java中的多线程笔记

    1. `interrupt()`:用于设置线程的中断标志位,如果线程正在阻塞(如等待 I/O 或调用 `sleep()`、`wait()` 等),则会抛出 `InterruptedException`,使线程从阻塞状态恢复并清除中断标志。 2. `isInterrupted()`:...

    挂起和恢复线程的资源

    在Java中,`resume()`方法已被弃用,取而代之的是使用中断机制(`interrupt()`)或者使用`join()`方法来控制线程的恢复。在C++中,可以使用`pthread_continue()`来恢复线程,但这同样需要操作系统级别的支持。 为了...

    中断信号处理

    在计算机系统中,信号(Signal)是一种轻量级的、非阻塞的进程间通信方式,它允许操作系统向进程发送通知,告知进程发生了某种特定事件,如资源请求、异常条件或者用户交互。 信号产生的主要方式有两种:硬件中断和...

    STM32F103CB外部中断

    STM32F103CB支持多种类型的外部中断,包括线程模式和中断模式,以及上升沿、下降沿和双沿触发等。这些特性使得它能够灵活地处理各种输入信号,比如按钮的按下和释放。 在外部中断的应用中,首先需要配置GPIO端口...

    第5章(三)中断下半部处理机制1

    工作队列是由一组内核线程(中断守护线程)驱动的,这样即使有长时间的任务,也不会阻塞其他中断的处理。 **声明和使用小任务**: 在Linux中,开发者可以使用`DECLARE_TASKLET`宏声明一个小任务,并指定处理函数。...

    中断为什么不能睡眠

    处理完毕后,系统会恢复到中断发生前的状态继续执行原任务。在这个过程中,ISR扮演着至关重要的角色。 ### 一、为什么中断服务程序不能睡眠? #### 1.1 中断与ISR的关系 中断是硬件层面的概念,而ISR是软件层面的...

    windows中断.zip

    - ISR完成对中断事件的处理后,会恢复被中断程序的上下文,并返回到被中断的地方继续执行。 3. **中断向量表**: - Windows操作系统维护了一个中断向量表(Interrupt Vector Table, IVT),其中每个条目都包含一...

    理解多线程,写一个多线程应用程序,要求能在用户级实现线程的调度,如启动、挂起、恢复、停止,的C thread、java thread实现。

    这意味着当一个线程阻塞(如等待I/O操作)时,程序需要决定哪个线程应该获得CPU资源。在单个CPU上,这通常意味着在可运行的线程之间切换。在多核系统中,每个核心可以并发地运行不同线程,进一步提高了并行性。 在...

    怎么干净的终止一个线程

    本文将详细介绍如何通过插入异常来实现线程的干净终止,并讨论防止线程阻塞的策略。 首先,让我们来看看如何通过插入异常来终止线程。这种方法通常涉及以下步骤: 1. 暂停目标线程:使用操作系统提供的API(例如...

    基于软中断的进程间通信的设计

    软中断作为进程间通信的一种手段,其主要优势在于可以异步地通知其他进程,而不会阻塞当前执行的进程。在Linux系统中,软中断通常由软件指令触发,如发送I/O完成信号。通过注册中断处理程序,当软中断发生时,操作...

Global site tag (gtag.js) - Google Analytics