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. IIS发布ASP程序问题汇总

    看异常位置,因为域的问题

  2. python+echarts==pycharts

    Django数据可视化 pyechats http://pyecharts.org/#/zh-cn/django

  3. Java FileInputStream与FileReader的区别

    在解释Java中FileInputStream和FileReader的具体区别之前,我想讲述一下Java中InputStream和Reader的根本差异,以及分别什么时候使用InputStream和R ...

  4. networkX如何读取存储图的二进制.dat文件

    一般情况下,.dat文件存储的是图的二进制邻接矩阵. import networkx as nx G = nx.readadjlist('auth_graph.dat')

  5. P2045 方格取数加强版 最大费用最大流

    $ \color{#0066ff}{ 题目描述 }$ 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每 ...

  6. Eclipse中文件夹变成包的解决办法(python版)

    问题展示如下: 如图,框中的三个文件夹都变成了包的样子. 解决方法如下: 1.在项目文件夹上右键,打开属性框 2.将PYTHONPATH中,Source Folders中的文件夹都删除.即可看到包已变 ...

  7. Linux常用的命令(3)

    1 文件的内容显示 cat 显示全部 more: 分屏幕显示,只能向后翻 less: 分屏幕显示,可以向上翻 head:查看前n行 默认10行 tail:查看后n行 -n -f: 查看文件尾部,不退出 ...

  8. iframe里面的元素触发父窗口元素事件的jquery代码 转

    例如父窗口定义了一个事件. top: $(dom1).bind('topEvent', function(){}); 那么iframe里面的元素怎样触发父窗口dom1的事件呢?这样吗? $(dom1, ...

  9. bzoj4548: 小奇的糖果 题解

    题目链接 题解 不包含所有颜色 就强制不选一个颜色 图中圆点颜色相同 矩形越大,包括的点一定不比其一小部分少 如图所示,最大矩形只有3种 离散化\(x\)坐标 然后按\(y\)排序 每次取出颜色的前驱 ...

  10. mysql一些简单操作

    创建数据库,删除数据库 create database databasename charset utf8 collate utf8_general_ci;设置字符集utf8,校对规则utf8_gen ...