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. php文件下载方法收藏(附js下载技巧)

    function down($url){ header('Content-Description: File Transfer'); header('Content-Type: application ...

  2. 字符串变dict

    1.eval 2.json # NameError: name # 'null' is not defined # i_dict=eval(i) 这种方式,如果dict字符串中有null ,将不能变成 ...

  3. NFS服务器的搭建与使用,实现数据同步

    NFS的基本架构,如下图所示: NFS服务是基本RPC协议的,所以安装NFS的前提要安装RPC协议,就像java语言一定要基于jdk一样! 下面的搭建centos-1作为服务端模拟A服务器,cento ...

  4. [洛谷 P4612][COCI 2011-2012#7] Setnja

    传送门 TM :setnja (1S256M) 一个人要散步去会见他的 N 个朋友(按给定的顺序会见).我们可以理解成他们都住在一个 很大的网格内,每个朋友住其中的一个单元格,所有人每一步都可以走到相 ...

  5. sharepoint_study_5

    描述:手动进行SharePoint网页调试图解 解决: 第一步:打开页面的后台代码,设置断点 第二步:添加到进程 第三步:选择SharePoint进程,我这里都选了,如果你知道要调试的页面是哪一个进程 ...

  6. BT网站--Python开发爬虫代替.NET

    BT网站-奥修磁力-Python开发爬虫代替.NET写的爬虫,主要演示访问速度和在一千万左右的HASH记录中索引效率. IBMID 磁力下载- WWW.IBMID.COM  现在用的是Python + ...

  7. Wannafly挑战赛14 - E 并查集维护线性基区间

    给一个1-base数组{a},有N次操作,每次操作会使一个位置无效.一个区间的权值定义为这个区间里选出一些数的异或和的最大值.求在每次操作前,所有不包含无效位置的区间的权值的最大值. 线性基删除不知道 ...

  8. c# 多数值区间判断是否有重叠

    /// <summary> /// 金额区间判断帮助类 /// </summary> public static class DecimalRangeHelper { /// ...

  9. 将M个客服随机分配给N个客户

    class AllocUser { //客户多于客服 public static void Test() { var customers = new List<Customer>() { ...

  10. MariaDB 密码,新用户添加

    修改root密码1.以root身份在终端登陆(必须)2.输入 mysqladmin -u root -p password ex后面的 ex 是要设置的密码3.回车后出现 Enter password ...