`
frank-liu
  • 浏览: 1682642 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Thread interrupt方法解析

阅读更多

初步理解

    我们在看一些多线程代码的时候,有的时候会碰到使用interrupt()方法的时候。从字面的意思来理解,应该就是中断当前正在执行的线程。那么,对于一个我们设计的普通线程来说,如果我们在主线程里调用它的interrupt()方法,会不会导致它被中断呢?

    比如说我们先写一段如下的代码:

import java.util.concurrent.TimeUnit;

public class ThreadCon extends Thread
{
    public void run()
    {
       
        for(int i = 0; i < Integer.MAX_VALUE; i++)
        {
            System.out.println(i);
        }
        
    }

    public static void main(String[] args)
    {
        ThreadCon thread = new ThreadCon();
        thread.start();
        System.out.println("main thread");
        try 
        {
            TimeUnit.SECONDS.sleep(2);
        } 
        catch(InterruptedException e) 
        {
            e.printStackTrace();
        }
        thread.interrupt();
    }
}

    这是一段比较简单的示例,我们在开始的时候启动一个子线程,这个线程打印从0到Integer.MAX_VALUE 的值。而主线程先sleep 2秒钟。然后再尝试去中断子线程。

    如果我们去运行前面这一段代码,会发现子线程会一直在输出数字结果,它根本就不会停下来。部分结果的输出如下:

141318
141319
141320
141321
141322
141323
141324
141325

     由此可见,我们对一个子线程发interrupt的消息时,如果线程是在运行的状态之下,它会忽略这个请求而继续执行的。

    那么,在什么情况下才会导致这个触发的interrupt消息让子线程能够响应呢?

interrupt方法处理方式

    interrupt方法调用的时候会设置该线程的interrupt标识位(flag),相当于设置了一个状态信息。执行的子线程需要检查该标识位是否被设置了然后才能做后续的执行步骤。这个检查的方法就是isInterrupted()。这样,在一旦检测到这个位被设置之后,我们就可以采取对应的措施。

    我们在前面的代码的基础上做一点修改:

import java.util.concurrent.TimeUnit;

public class ThreadCon extends Thread
{
    public void run()
    {
       
        for(int i = 0; i < Integer.MAX_VALUE; i++)
        {
            System.out.println(i);
            if(isInterrupted())
            {
                System.out.println("Interrupted...");
                return;
            }
        }
        
    }

    public static void main(String[] args)
    {
        ThreadCon thread = new ThreadCon();
        thread.start();
        System.out.println("main thread");
        try 
        {
            TimeUnit.SECONDS.sleep(2);
        } 
        catch(InterruptedException e) 
        {
            e.printStackTrace();
        }
        thread.interrupt();
    }
}

     这里,我们在run方法的循环里增加了一个判断,调用isInterrupted方法。如果被设置为interrupted,则显示一个信息然后退出。这个时候如果我们再执行这部分代码,会发现结果如下:

141370
141371
141372
141373
141374
141375
141376
141377
141378
Interrupted...

     所以说,从前面的代码中可以看到,这是一种处理interrupt方法的手段。在实际的一些应用中,我们可以通过抛出异常然后由调用程序捕捉的方式来处理。比如在前面的这个示例里,我们判断了isInterrupted了之后就在接着的部分处理了。如果我们希望由调用该方法的使用者来处理。可以在这里不做进一步的处理而是直接写一个throw new InterruptedException()。

这里也有一个稍微复杂点的示例,通过遍历文件系统,然后在处理的子方法里面来抛出异常,再由调用的方法来处理。

import java.io.File;

public class FileSearch implements Runnable {
	private String initPath;
	private String fileName;
	
	public FileSearch(String initPath, String fileName) {
			this.initPath = initPath;
			this.fileName = fileName;
	}
	
	@Override
	public void run() {
		File file = new File(initPath);
		if(file.isDirectory()) {
			try {
				directoryProcess(file);
			} catch(InterruptedException e) {
				System.out.printf("%s: The search has been interrupted", 
						Thread.currentThread().getName());
			}
		}
	}
	
	private void directoryProcess(File file) throws InterruptedException {
		File[] list = file.listFiles();
		if(list != null) {
			for(int i = 0; i < list.length; i++) {
				if(list[i].isDirectory()) {
					directoryProcess(list[i]);
				} else {
					fileProcess(list[i]);
				}
			}
		}
		if(Thread.interrupted()) {
			throw new InterruptedException();
		}
	}
	
	private void fileProcess(File file) throws InterruptedException {
		if(file.getName().equals(fileName)) {
			System.out.printf("%s : %s\n", Thread.currentThread().getName(),
					file.getAbsolutePath());
		}
		if(Thread.interrupted()) {
			throw new InterruptedException();
		}
	}
}

 启用该线程的部分代码如下:

import java.util.concurrent.TimeUnit;

/**
 *  Main class of the example. Search for the autoexect.bat file
 *  on the Windows root folder and its subfolders during ten seconds
 *  and then, interrupts the Thread
 */
public class Main {

	/**
	 * Main method of the core. Search for the autoexect.bat file
	 * on the Windows root folder and its subfolders during ten seconds
	 * and then, interrupts the Thread
	 * @param args
	 */
	public static void main(String[] args) {
		// Creates the Runnable object and the Thread to run it
		FileSearch searcher=new FileSearch("C:\\","autoexec.bat");
		Thread thread=new Thread(searcher);
		
		// Starts the Thread
		thread.start();
		
		// Wait for ten seconds
		try {
			TimeUnit.SECONDS.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		// Interrupts the thread
		thread.interrupt();
	}

}

 

总结

    interrupt方法的效果是它会设置线程的状态位,但是对于正在运行状态的线程并不会导致它被立即中断。只有执行的线程在检测到相关信息后采取对应措施。我们常用的措施一般是调用isInterrupted方法或者捕捉被调用方法抛出的InterruptedException来做处理。整体的应用并不复杂。

 

参考材料

http://stackoverflow.com/questions/3590000/what-does-java-lang-thread-interrupt-do

2
2
分享到:
评论

相关推荐

    浅谈Java线程Thread之interrupt中断解析

    Java线程Thread之interrupt中断解析 Java线程Thread之interrupt中断机制是Java多线程编程中的一种重要机制。通过调用Thread.interrupt()方法,可以设置线程的中断状态位,线程会不时地检测这个中断标示位,以判断...

    Interrupt方法结束线程

    下面是关于`interrupt()`方法以及线程中断机制的详细解析: 1. **线程的中断状态**: - 线程中断主要是通过设置线程的中断标志来实现的。当调用`Thread.interrupt()`方法时,目标线程的中断标志会被置为true。 2....

    java线程强制停止的两个Demo

    Java推荐使用更安全的中断机制,即通过`Thread.interrupt()`方法向线程发送中断信号,然后在线程的run方法中定期检查`isInterrupted()`或`interrupted()`状态来优雅地停止线程。这种方式允许线程清理资源并正常退出...

    Android Handler机制解析

    Thread的常用方法: * start():启动线程 * run():线程的执行体 * stop():停止线程 * sleep():线程睡眠 * interrupt():线程中断 Thread的常用字段: * Thread priority:线程优先级 * Thread state:线程状态...

    Socket与Thread扫描端口

    ### Socket与Thread扫描端口知识点解析 #### 一、Socket编程基础 在计算机网络中,Socket(套接字)是一种用于实现不同计算机间通信的技术。它通过定义一系列接口来完成数据在网络间的传输。Socket可以分为两种...

    Java Thread多线程详解及用法解析

    - **继承Thread类**:创建一个新的类,该类继承自Thread类,并重写run()方法。然后创建这个新类的实例并调用start()方法启动线程。示例代码如下: ```java public class ThreadDemo1 { public static void main...

    java多线程Thread的实现方法代码详解

    本篇文章将详细解析Thread类中的start()、run()、stop()、interrupt()、isInterrupted()、join()以及join(long millis)等方法。 1. **start()** `start()`方法是启动线程的核心方法。当调用一个Thread对象的`...

    java资料\、文件资料、多线程和xml解析_资料汇总

    为了确保唯一性,存入 `HashSet` 的对象必须正确地重写 `hashCode()` 和 `equals()` 方法。 - **用途**:适用于需要快速查找和添加元素的场景。 - **排序**:不保证元素的任何特定顺序。 ##### TreeSet - **特点**...

    Java多线程与并发系列22道高频面试题(附思维导图和答案解析)

    使用interrupt方法中断线程。 三、notify和notifyAll的区别 notify和notifyAll都是用于线程间的通信的方法,但是它们有着不同的作用域。notify可能会导致死锁,而notifyAll则不会。notifyAll可以唤醒所有处于wait...

    Java多线程程序设计详细解析.pdf

    Java中的线程中断是一种协作机制,允许一个线程通知另一个线程,当一个线程调用另一个线程的interrupt()方法时,被中断的线程会在适当的时候响应这个中断。例如,一个处于阻塞状态的线程在接收到中断信号后会抛出...

    stm32试题(卷)与答案解析.doc

    NVIC(Nested Vectored Interrupt Controller)可以用来表示优先权等级的位数可配置为2、4、6或8位。 三、Cortex-M系列发布版本 Cortex-M系列正式发布的版本有Cortex-M3、Cortex-M4、Cortex-M7等。 四、流水线...

    《JAVA语言程序设计》期末考试试题及答案5(应考必备题库)推荐文档.doc

    - **interrupt() 方法**:`Thread` 类中的 `interrupt()` 方法用于中断一个线程。如果目标线程正处于阻塞状态(如休眠、等待或阻塞I/O),那么该方法会立即抛出 `InterruptedException`。 - **InterruptedException*...

    多线程试卷参考答案.pdf

    - interrupt()方法用于中断线程,中断后线程中抛出InterruptedException异常。 - join()方法可以使一个线程等待另一个线程完成其任务。 6. Thread类中的其他方法: - sleep(long millis)方法可以将线程挂起指定...

    Android 实现界面刷新的几种方法

    Thread.currentThread().interrupt(); } } } } ``` 通过这种方式,后台线程中的`GameThread`会周期性地向主线程发送消息,然后由Handler处理并调用`invalidate()`刷新界面。 ### 使用`postInvalidate()`刷新...

    多线程在VisualStudioC#的应用实例教程[收集].pdf

    Thread类提供了多种方法来控制线程的状态和行为,以下是Thread类中的常用方法: * Abort:调用此方法通常会终止线程,但会引起ThreadAbortException类型异常。 * Interrupt:中断处于WaitSleepJoin线程状态的线程。...

    java 多线程实例

    当一个线程处于阻塞状态(如等待、睡眠或锁等待)时,调用`interrupt()`方法可以使其被中断。这通常会导致一个`InterruptedException`被抛出。 - **interrupted()方法**:这是一个静态方法,用来检查当前线程是否被...

    Java线程的相关方法详细解析

    下面将对Java线程的主要方法进行详细解析: 1. **start()** - 这个方法是启动线程的关键,当你创建了一个`Thread`对象后,必须调用`start()`方法来启动它。这个方法会调用线程的`run()`方法,但区别在于`start()`会...

Global site tag (gtag.js) - Google Analytics