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. CentOS 6.3下Samba服务器的安装与配置【转载】

    本文转载自 园友David_Tang的博客,如有侵权请联系本人及时删除,原文地址: http://www.cnblogs.com/mchina/archive/2012/12/18/2816717.h ...

  2. [SCOI2007]最大土地面积(旋转卡壳)

    首先,最大四边形的四个点一定在凸包上 所以先求凸包 有个结论,若是随机数据,凸包包括的点大约是\(\log_2n\)个 然鹅,此题绝对不会这么轻松,若\(O(n^4)\)枚举,只有50分 所以还是要想 ...

  3. win10进入安全模式的方法

    https://jingyan.baidu.com/article/a3aad71ac5919bb1fa009667.html

  4. java 常用模块代码

    1.文件的读写操作 (1)进行读操作 import java.io.BufferedReader; import java.io.FileNotFoundException; import java. ...

  5. R语言结果输出方法

    输出函数:cat,sink,writeLines,write.table 根据输出的方向分为输出到屏幕和输出到文件. 1.cat函数即能输出到屏幕,也能输出到文件. 使用方式:cat(... , fi ...

  6. D. Diverse Garland-----CF字符串

    D. Diverse Garland time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  7. windows同时安装python2和python3两个版本

    1.安装python2 下载地址: https://www.python.org/downloads/windows/ 进入页面,下拉,64位系统要选择这个. 下载完成后,一直点击下一步,直到安装完毕 ...

  8. Mac下Jenkins+SVN+Xcode构建持续导出环境

    1 安装Jenkins Jenkins是基于Java开发的一种持续集成工具.所以呢,要使用Jenkins必须使用先安装JDK. JDK安装 JDK 下载地址 jdk 1.8.png 安装JDK的过程略 ...

  9. linux 输出 之 nl 命令

    1.命令格式:nl [选项]... [文件]... 2.命令参数: -b  :指定行号指定的方式,主要有两种: -b a :表示不论是否为空行,也同样列出行号(类似 cat -n): -b t :如果 ...

  10. golang context 剖析 1.7.4 版本

    1. 内部结构之 - timerCtx . type timerCtx struct { cancelCtx timer *time.Timer // Under cancelCtx.mu. dead ...