1. 线程阻塞状态与等待状态(当一个线程处于被阻塞或等待状态时,它暂时不活动,不允许任何代码且消耗最少的资源)
    • 当一个线程试图获得一个内部的对象锁(而不是java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态
    • 当一个线程等待另一个线程通知调度器的一个条件时,它自己进入等待状态。在调用Object.wait方法或Thread.join方法,或者是等待java.util.concurrent库中的Lock或Condition时,就会出现这种情况。实际上被阻塞状态与等待状态是有很大不同的
    • 带有超时参数的方法,调用它们线程会进入计时等待状态。这一状态将一直保持到超时期满或者接收到适合的通知。带有超时的方法有Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
  2. 没有强制线程终止的方法。然而Interrupt方法可以用来请求终止线程,当对一个线程调用interrupt方法时,线程的中断状态被置位,这是每一个线程都有的boolean状态,每个线程应该不是的检查这个标志,以判断线程是否被中断。当一个线程的中断状态被置位时,被中断的线程决定如何响应中断
    • intrrupt方法,用来中断线程
    • interrupted是一个静态方法,它检测当前线程是否被中断。而且,该方法会清除该线程的中断状态,重置中断状态为false
    • isInterrupted是一个实例方法,检验是否有线程被中断,不会改变中断状态
  3. 线程中断时抛出InterruptedException异常解析
    • 当一个线程调在sleep方法时,如果在该线程上调用interrupt方法,将抛出异常
    • 当一个线程进入一个同步阻塞( synchronize(o))的等待集wait时,调用interrupt方法,将抛出异常
    • 当线程等待concurrent库中锁Lock时,被中断不抛异常
    • 当线程进入concurrent库中条件等待集await时,被中断不抛异常
    • 如果在中断状态被置位时调用sleep方法,不会休眠,反而会清除这一状态(!)并抛出InterruptException异常
  4. 锁测试与超时
    • tryLock方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false。而且线程可以离开去做其他事情
      • lock方法不能被中断。如果一个线程在等待获得一个锁时被中断,并不会抛出异常。中断线程在获得锁之前一直处于阻塞状态。如果出现死锁,那么,lock方法就无法终止
      • 然而,如果调用带有超时参数的tryLock(1000,TimeUnit.MILLISECONDS),那么如果线程在等待期间被中断,将会抛出InterruptedException异常。这是一个非常有用的特性,因为允许程序打破死锁
// 当一个线程调在sleep方法时,如果在该线程上调用interrupt方法
public class Demo {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
t.interrupt(); // 抛出异常
}
} // 当一个线程进入一个同步阻塞( synchronize(o))的等待集wait时
public class Demo {
public Object o = new Object();
public void fun() throws InterruptedException {
synchronized (o) {
o.wait();
}
}
public static void main(String[] args) throws InterruptedException {
Demo demo = new Demo();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
demo.fun();
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
t.interrupt(); // 抛出异常
}
} // 当线程等待concurrent库中锁Lock时
public class Bank {
private Lock bankLock;
private Condition sufficientFunds;
public Bank() {
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}
public void transfer() throws InterruptedException {
bankLock.lock(); // 线程t2不抛出异常,可能发生同步阻塞,建议使用带超时的tryLock(1000,TimeUnit.MILLISECONDS),调用interrupt时抛出异常
// if (bankLock.tryLock()) // 线程t2获取不到锁,立即离开做其他事情
// if (bankLock.tryLock(3000, TimeUnit.MILLISECONDS)) // 线程t2抛出异常
// {
try {
while (true) {
}
} finally {
bankLock.unlock();
}
// }
}
public static void main(String[] args) throws InterruptedException {
Bank bank = new Bank();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
bank.transfer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
bank.transfer();
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
Thread.sleep(2000);
t2.interrupt();
}
} // 当线程进入concurrent库中条件等待集await时
public class Bank {
private Lock bankLock;
private Condition sufficientFunds;
public Bank() {
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition(); }
public void transfer(boolean b,boolean c) throws InterruptedException {
bankLock.lock();
try {
if (b)
sufficientFunds.await();
while (c) { }
sufficientFunds.signalAll();
} finally {
bankLock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
Bank bank = new Bank();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
bank.transfer(true,false);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
bank.transfer(false,true);
System.out.println("end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
Thread.sleep(2000);
t1.interrupt();
}
}

  

 
 

线程的Interrupt方法与InterruptedException解析的更多相关文章

  1. 日积月累--线程中断interrupt()方法

    线程中断方法interrupt()方法的理解: interrupt()方法的源码: interrupted()方法的源码及注解: isInterrupted()方法源码及注解: 在了解这个方法之前我们 ...

  2. Java线程停止interrupt()方法

    程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误.在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程. 中 ...

  3. java线程的interrupt方法

    java现成的interrupt方法比较容易误导新手,它其实是不会中断(停止)当前的线程,只是标志一下当前线程的某个状态值(中断标志位),并且这个状态为只对阻塞方法(比如说:             ...

  4. Thread的中断机制(interrupt),循环线程停止的方法

    一.中断原理 中断线程 线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个 ...

  5. 线程终止的四种方式,interrupt 方法使用的简单介绍。

    一 正常结束. package com.aaa.threaddemo; /* 一 终止线程的四种方式? * 程序运行结束,线程终止. * */ public class ThreadTerminati ...

  6. Java面试中的“劲敌”线程,9个疑问全面解析

    作者:我是攻城师 (一)创建线程的方式 (1)实现Runnable接口 (2)继承Thread类 推荐使用接口,能够做到定义与实现分离,耦合更低 (二)关于线程的优先级 thread2.setPrio ...

  7. Java 多线程 interrupt方法

    interrupt 下面是interrupt方法的文档的一部分: * <p> If this thread is blocked in an invocation of the {@lin ...

  8. interrupt()方法的简单理解

    interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程.这一方法实际完成的是,给受阻塞的线程发出一个中断信号,这样受阻线程就得以退出阻塞的状态.更确切的说,如果线程被Objec ...

  9. Java 并发:线程中断-interrupt

    一直以为执行了interrupt方法就可以让线程结束,并抛出InterruptedException. 今天看了Java并发编程实战的第七章发现并不是这么回事,在这章的开头就提到 要使任务和线程能安全 ...

随机推荐

  1. Java面向对象之多态(向上、向下转型) 入门实例

    一.基础概念 多态: 重点是对象的多态性.某一事物的多种体现形态. 多态的作用: 1.提高了代码的扩展性,后期出现的功能,可以被之前的程序所执行. 2.不能使用子类特有的功能.只能使用覆盖父类的功能. ...

  2. HttpClient 基于连接池的使用

    场景:调用外部系统接口的http请求 要求: 1:可能是http请求,也可能是https请求 2:需要加入连接池的概念,不能每次发起请求都新建一个连接(每次连接握手三次,效率太低) 准备使用httpc ...

  3. J2EE 的体系结构

    J2EE 即Java2平台企业版,它提供了基于组件的方式来设计.开发.组装和部署企业应用.J2EE使用多层分布式的应用模型,这个多层通常通过三层或四层来实现: 1.客户层,运行在客户计算机上的组件.  ...

  4. SQL Server 数据类型与.Net Framework平台映射

    SQL Server 和 .NET Framework 基于不同的类型系统.  例如,.NET Framework Decimal 结构的最大小数位数为 28,而 SQL Server 的 decim ...

  5. 获取当前按钮或者html的ID名称

    今天做的上传图片,点击图片删除. 随机给图片id,获取图片id,然后删除图片. 由于图片id是随机的,用点击img或者点击class,获取id都不行,最后用onclick事件获取. js代码如下: $ ...

  6. AtCoder - 2566 优先队列

    Let N be a positive integer. There is a numerical sequence of length 3N, a=(a1,a2,…,a3N). Snuke is c ...

  7. TX2 Clone

    由于给TX2配置了很多的开发环境,也修改了一些驱动,想将这些环境能够完整的迁移到一块bare TX2,于是尝试了clone的方法. 这种方法的优点是: 确保了移植的TX2 与已经配置好的环境是一致的: ...

  8. Android 连接服务器,并进行相关操作

    1.连接服务器 (1)直接使用WINDOWS自带的远程桌面连接 win+R调出DOS操作窗口,输入mstsc.exe 点击确定,进入如下界面: 点击连接,输入用户名和密码登录,电脑会进入服务器界面.

  9. SQL 随手记

    SQL 学习片段: 建立一个简单的联系数据表, mobile_number char(11).mobile_province nvarchar(50).mobile_area nvarchar(200 ...

  10. 119th LeetCode Weekly Contest Subarray Sums Divisible by K

    Given an array A of integers, return the number of (contiguous, non-empty) subarrays that have a sum ...