一、线程的状态

线程可以阻塞于四种状态:

1、当线程执行Thread.sleep()时,它一直阻塞到指定的毫秒时间之后,或者阻塞被另一个线程打断;

2、当线程碰到一条wait()语句时,它会一直阻塞到接到通知notify()、被中断、经过了指定时间为止(若有超时值的话)

3、线程阻塞与不同I/O的方式

3.1. 常见的一种方式是InputStream的read()方法,该方法一直阻塞到从流中读取一个字节的数据为止,它可以无限阻塞,因此不能指定超时时间;

  3.2 java.nio 中的非阻塞 I/O 类也不支持可中断 I/O,但是同样可以通过关闭通道或者请求 Selector 上的唤醒来取消阻塞操作

4、线程也可以阻塞等待获取某个对象锁的排他性访问权限(即等待获得synchronized语句必须的锁时阻塞)。

注意,并非所有的阻塞状态都是可中断的,以上阻塞状态的前两种可以被中断,后两种不会对中断做出反应

wait vs blocked

假设t1,t2先后两个线程,都执行如下代码:

  1. synchronized(Obj) {
  2. Obj.wait();
  3. }

t1先进,最后在Obj.wait()下卡住,这时java管t1的状态waitting状态

t2后进,直接在第一行就卡住了,这时java叫t2为blocked状态。

请注意,blocked是过去分词,意味着他是被卡住的。因为这段代码只让一条线程运行。同时,jvm是知道怎么结束blocked的,只要别的线程退出这段代码,他就会自动让你进去。也就是说别的线程无需唤醒你,由jvm自动来干

而waiiting是说我调用wait()等函数,主动卡住自己(我在等一个白富美),请jvm在满足某种条件后(白富美发消息让我们晚上见),比如另条线程调用了notify()后,把我唤醒。这个唤醒的责任在于别的线程(白富美)明确的调用一些唤醒函数。

做这样的区分,是jvm出于管理的需要,做了这种区分,比如两个原因的线程放两个队列里管理,如果别的线程运行出了synchronized这段代码,我只需要去blocked队列,放个出来。而某人调用了notify(),我只需要去waitting队列里取个出来。

P.S. 从linux内核来看,这些线程都是等待状态,没区别,区别只在于java的管理需要。通常我们在系统级别说线程的blocked,是说线程操作io,被暂停了,这种线程由linux内核来唤醒(io设备报告数据来了,内核把block的线程放进可运行的进程队列,

 
依次得到处理器时间),而wait是说,等待一个内核mutex对象,另个线程signal这个mutex后,这个线程才可以运行。区别在于由谁唤醒,是操作系统,还是另一个线程,这里倒和java很相似。

二、中断某个线程

当对一个线程,调用 interrupt() 时

① 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true。被设置中断标志的线程将继续正常运行,不受影响。

② 如果线程处于被阻塞状态(sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException

interrupt() 并不能真正的中断线程,需要被调用的线程自己进行配合才行

① 在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程

② 在调用阻塞方法时正确处理InterruptedException异常

1。当线程没有处于阻塞状态,通过改变标志量,可以让线程停止。

  1. public class Example01 extends Thread {
  2. boolean stop=false;
  3. public static void main( String args[] ) throws Exception {
  4. Example01 thread = new Example01();
  5. thread.start();
  6. Thread.sleep(1000);
  7. thread.interrupt(); //线程不会停止
  8. // thread.stop = true; //线程会停止
  9. }
  10. public void run() {
  11. while(!stop){
  12. System.out.println( "Thread is running..." );
  13.  
  14. }
  15. System.out.println("Thread exiting..." );
  16. }
  17. }

2。当线程处于阻塞状态,调用interrupt()方法。

  If this thread is blocked in an invocation of the wait() methods of the Object class, or of the join(), , sleep(long)methods of

Thread class, then its interrupt status will be cleared and it will receive an InterruptedException.

  1. public class Example01 extends Thread {
  2. boolean stop=false;
  3. public static void main( String args[] ) throws Exception {
  4. Example01 thread = new Example01();
  5. thread.start();
  6. Thread.sleep(1000);
  7. thread.interrupt();
  8.  
  9. }
  10. public void run() {
  11. System.out.println("-------sleeping");
  12. try {
  13. Thread.sleep(2000);
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. System.out.println("-------caclulating");
  18. double d = 0;
  19. for(int i=1; i<2500000; i++){
  20. d += Math.E/d;
  21. }
  22. System.out.println("-------finish caclulating");
  23.  
  24. }
  25. }

3.当线程处于阻塞状态,可以中断等待的资源,如I/O, Socket

参考:

IBM: 处理InterruptedException

self: AQS 与 LockSupport

Java 如何中断和恢复线程的执行的更多相关文章

  1. java中怎么终止一个线程的执行----个人学习心得

    参考了一下两个网站的介绍: ①:http://blog.csdn.net/liuhanhan512/article/details/7077601 ②:http://www.blogjava.net/ ...

  2. JAVA多线程之当一个线程在执行死循环时会影响另外一个线程吗?

    一,问题描述 假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗? 二,示例代码(代码 ...

  3. 面试必问!Java 多线程中两个线程交替执行,一个输出偶数,一个输出奇数

    前言 楼主今天在面经上看到这个题,挺有意思,小小的题目对多线程的考量还挺多.大部分同学都会使用 synchronized 来实现.楼主今天带来另外两种优化实现,让你面试的时候,傲视群雄! 第一种 sy ...

  4. java中等待所有线程都执行结束(转)

    转自:http://blog.csdn.net/liweisnake/article/details/12966761 今天看到一篇文章,是关于java中如何等待所有线程都执行结束,文章总结得很好,原 ...

  5. java中等待所有线程都执行结束

    转自:http://blog.csdn.net/liweisnake/article/details/12966761 今天看到一篇文章,是关于java中如何等待所有线程都执行结束,文章总结得很好,原 ...

  6. Java并发编程基础--基本线程方法详解

    什么是线程 线程是操作系统调度的最小单位,一个进程中可以有多个线程,这些线程可以各自的计数器,栈,局部变量,并且能够访问共享的内存变量.多线程的优势是可以提高响应时间和吞吐量. 使用多线程 一个进程正 ...

  7. 【Java并发编程】:线程挂起、恢复与终止

    挂起和恢复线程     Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的.如果在不合适的时候挂起线程(比如,锁定共享资源时 ...

  8. ThreadPoolExecutor源码分析-面试问烂了的Java线程池执行流程,如果要问你具体的执行细节,你还会吗?

    Java版本:8u261. 对于Java中的线程池,面试问的最多的就是线程池中各个参数的含义,又或者是线程池执行的流程,彷佛这已成为了固定的模式与套路.但是假如我是面试官,现在我想问一些更细致的问题, ...

  9. java线程中断和终止线程运行

    ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程 ...

随机推荐

  1. 简单html弹窗

    css: <style type="text/css"> .moneyrecord { display:none; border:0.5em solid #00AAEE ...

  2. (记录)eclipse常用设置步骤

    代码风格文件导入: https://blog.csdn.net/wangming520liwei/article/details/53911736 注释中的author修改: https://jing ...

  3. c++ word类型

    word就是16位的数据 随着机器的发展,C++语言本身并没有规定short的位数,不一定是十六位的(随着计算机的发展,可能改变).但word将永远是16位的--机器发展后只需要修改,typedef ...

  4. 插入数据insert语句中出错:没有与这些操作数匹配的“+”运算符,操作数类型为:const char[ ]+CString

    UpdateData(); CString n; n.Format(L"%d", m_n); _bstr_t strCmd_n = "insert into n(材料,折 ...

  5. MySQL Server 5.7.13

    如何安装MySQL,MySQL两种安装方式_百度经验 http://jingyan.baidu.com/article/cd4c2979033a17756f6e6047.html "C:\P ...

  6. JavaScript------去掉Array中重复值

    转载: http://blog.csdn.net/teresa502/article/details/7926796 代码: // 删除数组中重复数据 function removeDuplElem( ...

  7. HTML&CSS精选笔记_列表与超链接

    列表与超链接 列表标记 无序列表ul 无序列表的各个列表项之间没有顺序级别之分,是并列的 <ul> <li>列表项1</li> <li>列表项2< ...

  8. python2.0_day18_django_ORM

    Django_ORMday15\16我们学到的ORM都是最基本的增删改查.下面我们稍作升级,学习下高级点的增删改查.先创建一个新的APP项目 python3. manage.py startapp b ...

  9. linux中的目录和文件的统计

    ls 目录 | wc -l find  ./   -type   d   |   wc   -l      //查找目录个数 find   ./   -type   f   |   wc   -l   ...

  10. ASP代码审计学习笔记 -3.上传漏洞

    1.ASP上传过程抓包分析: POST /4.asp HTTP/1.1 Host: 192.168.1.102 User-Agent: Mozilla/5.0 (Windows NT 10.0; WO ...