`

如何中断线程in Java

    博客分类:
  • Java
 
阅读更多

http://android.blog.51cto.com/268543/562374

 

如何中断Java线程?查看API,不就是用interrupt()方法么?而线程是否已经中断则用Thread.currentThread().isInterrupted()返回true/false:

public class ThreadDemo extends Thread{
        public static void main(String[] args) throws InterruptedException {
                Thread thread = new ThreadDemo();
                thread.start();
                thread.sleep(100);
                thread.interrupt(); //中断线程
        }

        @Override
        public void run() {
                while(!Thread.currentThread().isInterrupted()) {
                        System.out.println("thread running");

                        try {
                                Thread.sleep(100);
                        }catch(InterruptedException e)
                        {
                                System.out.println("InterruptedException");
                        }
                }

                System.out.println("thread interrupted");
        }
}

 运行结果:
thread running
InterruptedException
thread running
thread running
thread running
thread running
...

 

很快发现这方法似乎有问题,线程没有成功中断,于是在处理InterruptedException异常后调用break跳出while循环:

public class ThreadDemo extends Thread{
        public static void main(String[] args) throws InterruptedException {
                Thread thread = new ThreadDemo();
                thread.start();
                thread.sleep(100);
                thread.interrupt(); //中断线程
        }

        @Override
        public void run() {
                while(!Thread.currentThread().isInterrupted()) {
                        System.out.println("thread running");

                        try {
                                Thread.sleep(100);
                        }catch(InterruptedException e)
                        {
                                System.out.println("InterruptedException");
                                break;
                        }
                }

                System.out.println("thread interrupted");
        }
}
运行结果(线程成功中断):
thread running
InterruptedException
thread interrupted
 
接着在网上搜索了一下,写了一些例子研究后明白如何写一个可中断的线程。
首先发现在调用线程的start()后,立即调用interrupt()中断线程,线程停止了——被挡在while条件的外面:
public class ThreadDemo extends Thread{
        public static void main(String[] args) throws InterruptedException {
                Thread thread = new ThreadDemo();
                thread.start();
                //thread.sleep(100);
                thread.interrupt(); //中断线程
        }

        @Override
        public void run() {
                System.out.println("in run()");
                while(!Thread.currentThread().isInterrupted()) {
                        System.out.println("thread running");

                        try {
                                Thread.sleep(100);
                        }catch(InterruptedException e)
                        {
                                System.out.println("InterruptedException");
                                //break;
                        }
                }

                System.out.println("thread interrupted");
        }
}
 运行结果:
in run()
thread interrupted

然后按照网上说的在异常处理时再次中断,原来这样就能成功地用interrupt方法中断线程:
public class ThreadDemo extends Thread{
        public static void main(String[] args) throws InterruptedException {
                Thread thread = new ThreadDemo();
                thread.start();
                thread.sleep(100);
                thread.interrupt(); //中断线程
        }

        @Override
        public void run() {
                while(!Thread.currentThread().isInterrupted()) {
                        System.out.println("thread running");

                        try {
                                Thread.sleep(100);
                        }catch(InterruptedException e)
                        {
                                System.out.println("InterruptedException");
                                Thread.currentThread().interrupt(); //再次中断线程
                                //break;
                        }
                }

                System.out.println("thread interrupted");
        }
}
 运行结果(线程成功中断):
thread running
InterruptedException
thread interrupted

为什么在调用interrupt()前加上sleep(),导致的结果不同呢?
  我认为Thread对象只有在调用start()时才分配资源创建线程提供给CPU调度。而这过程需要时间,因为时间差,导致了在进入run()方法前,中断标志已经被set on,于是被挡在while条件上。
而再次中断线程,中断标志被set on了,然后循环回到while条件判断,于是退出循环。

而线程被中断后,该对象依然存在的,只是线程不能再次调用start()否则会报异常IllegalThreadStateException。
public class ThreadDemo extends Thread{
        public static void main(String[] args){
          try{
                 ThreadDemo thread = new ThreadDemo();
                 thread.start();
                 thread.sleep(100);

                 thread.interrupt(); //中断线程
                 thread.sleep(100);

                 thread.printStr();
                 thread.interrupt(); //第三次中断线程

                 thread.printStr();
                 thread.join();
          }catch(InterruptedException e){
            e.printStackTrace();
          }
        }

        private void printStr(){
          System.out.println("thread obj");
        }

        @Override
        public void run() {
                while(!Thread.currentThread().isInterrupted()) {
                        System.out.println("thread running");

                        try {
                                Thread.sleep(100);
                        }catch(InterruptedException e)
                        {
                                System.out.println("InterruptedException");
                                Thread.currentThread().interrupt(); //再次中断线程
                        }
                }

                System.out.println("thread interrupted");
        }
}
  运行结果:
thread running
InterruptedException
thread interrupted
thread obj
thread obj
 
简单总结:
1. 线程start()后马上调用interrupt(),在进入run()时中断标志已经被set on;
2. 在处理sleep()可能抛出的InterruptedException时,再次中断线程即可成功中断;
3. 注意interrupt()方法是set on 中断标志的,interrupted()方法是判断后并清除中断标志的。
 
isInterrupted()和interrputed()方法的区别
public static boolean interrupted()
    测试当前线程是否已经中断。线程的中断状态由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。
 
public boolean isInterrupted()
    测试线程是否已经中断。线程的中断状态不受该方法的影响。
 
两者都是如果该线程已经中断,则返回 true;否则返回 false。
 
 
参考文章 《Java 可中断线程》 http://blog.csdn.net/sapphiron/archive/2008/10/05/3018053.aspx 此文介绍更多的处理其他阻塞情况的中断方法。

 

分享到:
评论

相关推荐

    JAVA(坦克大战,多线程管理).rar

    在Java编程领域,多线程管理是开发高效并发应用程序的关键技术。"JAVA(坦克大战,多线程管理).rar"这个压缩包可能包含了一个基于Java实现的坦克大战游戏,其中涉及了多线程的概念来模拟游戏中的各种动态元素,如...

    Thinking in java 电子书

    6. **多线程**:Java提供了强大的多线程支持,书中详细讲解了线程的创建、同步、中断以及死锁问题,帮助读者构建出高效、安全的并发程序。 7. **网络编程**:Java的Socket编程使得网络通信变得简单,书中涵盖了TCP...

    Java 多线程学习总结归纳(附代码)

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,从而提升系统效率。在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。下面是对Java多线程学习的详细解析。 1. **多线程概述*...

    scalable io in java

    5. **中断和唤醒(Interrupt and Wakeup)**:NIO支持中断IO操作,当操作被中断时,系统会立即停止等待并抛出异常,使得线程可以更快地响应其他事件。 6. **文件系统操作的增强**:NIO还提供了一些高级文件系统功能...

    Thinking_in_Java_4th_edition.pdf_java_in_javase_

    8. **多线程**:Java提供了丰富的API支持多线程编程,包括线程的创建、同步、中断等,书中详细介绍了这部分内容。 9. **输入/输出流**:Java的I/O流系统涵盖了文件操作、网络通信等,书中讲解了流的层次结构、缓冲...

    java面试题之多线程

    在Java多线程编程中,面试题常常涉及到线程的基本概念、同步与异步的区别、线程同步方法以及Java提供的并发工具类。下面我们将深入探讨这些知识点。 1. **线程间的协作**: - `sleep()` 和 `wait()` 的区别:`...

    Thinking in Java 中文第四版+习题答案

    3.2.6 中断和继续 3.2.7 切换 3.3 总结 3.4 练习 第4章 初始化和清除 4.1 由构建器保证初始化 4.2 方法过载 4.2.1 区分过载方法 4.2.2 主类型的过载 4.2.3 返回值过载 4.2.4 默认构建器 4.2.5 this关键字 4.3 清除:...

    Scalable IO in Java doug lea.zip

    《Scalable IO in Java》是由Java领域知名专家Doug Lea撰写的一本关于Java高性能I/O编程的著作。这本书深入探讨了如何在Java环境中实现可扩展的输入/输出操作,特别是利用非阻塞I/O(Non-blocking I/O,简称NIO)...

    Java多线程与线程安全实践-基于Http协议的断点续传

    `Atomic`类提供原子操作,确保操作不会被线程中断;`Lock`接口提供了比`synchronized`更细粒度的锁控制。 在基于HTTP协议的断点续传中,我们通常会利用HTTP的Range请求头来实现。Range请求允许客户端指定要获取的...

    深入浅出java多线程代码示例

    以上只是Java多线程编程的基础知识,实际应用中还包括死锁检测、线程中断、线程安全的数据结构等更高级的主题。通过阅读`thread-in-imooc`和`Actor`中的代码示例,你可以更深入地了解并实践这些概念。

    Scalable IO in Java原文和翻译

    《Scalable IO in Java》是由Java领域的大师Doug Lea撰写的一份PPT文档,主要探讨了如何在Java环境中实现可扩展的I/O处理。本文将深入解析这份文档及其翻译,带你理解Reactor模式的设计原理及其在Java中的应用。 ...

    java_concurrency_in_practice_source源代码

    这里的"java_concurrency_in_practice_source"源代码正是书中实例的实现,它涵盖了Java多线程编程中的关键概念和技术。 1. **线程基础**:Java中创建线程有两种方式,一是通过`Thread`类的子类,二是实现`Runnable`...

    Java Concurrency in Practice.zip

    《Java Concurrency in Practice》是Java并发编程领域的一本经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和Doug Lea等专家共同编写。这本书深入探讨了Java平台上的多线程和并发编程,旨在...

    一本经典的多线程书籍 Java并发编程 设计原则与模式 第二版 (英文原版)

    《Java并发编程 设计原则与模式 第二版》是一本广受赞誉的经典书籍,由著名计算机科学家Doug Lea撰写,英文原版名为"Concurrent Programming in Java - Design Principles and Patterns, Second Edition"。...

    Thinking in Java简体中文(全)

    3.2.6 中断和继续 3.2.7 切换 3.3 总结 3.4 练习 第4章 初始化和清除 4.1 由构建器保证初始化 4.2 方法过载 4.2.1 区分过载方法 4.2.2 主类型的过载 4.2.3 返回值过载 4.2.4 默认构建器 4.2.5 this关键字 4.3 清除...

    Concurrent Programming in Java™: Design Principles and Patterns 2nd

    本书《Concurrent Programming in Java™: Design Principles and Patterns 2nd》由Doug Lea编写,出版于1999年,是关于Java并发编程的一本权威指南。Java平台因其强大的线程支持能力而备受青睐,这使得Java程序员...

    TCPIP Sockets in Java Practical Guide for Programmers

    3. **多线程编程**:由于网络通信通常涉及并发处理,书里可能会讨论如何使用Java的多线程机制来处理多个连接请求。 4. **异步I/O**:Java NIO(非阻塞I/O)库提供了一种更高效的方式来处理多个并发连接,可能包含...

    Doug Lea Scalable IO in Java

    《Doug Lea Scalable IO in Java》是一本深入探讨Java NIO(非阻塞I/O)和反应器设计模式的经典著作。作者Doug Lea是Java并发领域的权威,他对Java性能优化和系统设计有着深刻的洞察力。这本书对于理解如何在Java...

Global site tag (gtag.js) - Google Analytics