zoukankan      html  css  js  c++  java
  • Java多线程中断机制

    thread中的三个方法:interrupt()、interrupted()、isInterrupted()
    1、interrupt()
    public void interrupt() {
      if (this != Thread.currentThread())
        checkAccess();
     
      synchronized (blockerLock) {
        Interruptible b = blocker;
        if (b != null) {
        interrupt0();    // Just to set the interrupt flag
        b.interrupt();
        return;
        }
      }
      interrupt0();
      }
    
    
    /* Some private helper methods */
    private native void setPriority0(int newPriority);
    private native void stop0(Object o);
    private native void suspend0();
    private native void resume0();
    private native void interrupt0();
    
     
    分两部分看:
    (1)第一部分的第8行注释说得很清楚了,interrupt0()方法的作用是"Just to set the interrupt flag",即方法的作用仅仅是设置中断标识位
    (2)第二部分的第6行就是interrupt0()方法的原型,由于方法是被native修饰的,很明显这是一个本地方法,是Java虚拟机实现的。
    当对一个线程,调用 interrupt() 时,
    • 如果线程处于被阻塞状态(例如处于sleep, wait, join 等状态),那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常。
    • 如果线程处于正常活动状态,那么会将该线程的中断标志设置为 true。被设置中断标志的线程将继续正常运行,不受影响。
     
     
     
    2、isInterrupted()
    方法唯一的作用只是测试线程是否已经中断,中断标识位的状态并不受到该方法的影响,看一下Java是如何实现这个方法的:
    /**
     * Tests whether this thread has been interrupted. The <i>interrupted
     * status</i> of the thread is unaffected by this method.
     *
     * <p>A thread interruption ignored because a thread was not alive 
     * at the time of the interrupt will be reflected by this method 
     * returning false.
     *
     * @return <code>true</code> if this thread has been interrupted;
     *     <code>false</code> otherwise.
     * @see   #interrupted()
     * @revised 6.0
     */
    public boolean isInterrupted() {
    return isInterrupted(false);
    }
    
    private native boolean isInterrupted(boolean ClearInterrupted);
    
    注意一下第一部分的第2行和第3行,"The interrupted statis of the thread is unaffected by this method",即线程的中断状态不受到这个方法的影响。最终调用的是isInterrupted(boolean ClearInterrupted),这个方法是一个native的,看得出也是Java虚拟机实现的。方法的参数ClearInterrupted,顾名思义,清除中断标识位,这里传递false,明显就是不清除。
     
    3、interrupted()
    方法的作用是测试当前线程是否已经中断,线程的中断标识位由该方法清除。换句话说,连续两次调用该方法的返回值必定是false。看一下这个方法是如何实现的:
    /**
     * Tests whether the current thread has been interrupted. The
     * <i>interrupted status</i> of the thread is cleared by this method. In
     * other words, if this method were to be called twice in succession, the
     * second call would return false (unless the current thread were
     * interrupted again, after the first call had cleared its interrupted
     * status and before the second call had examined it).
     *
     * <p>A thread interruption ignored because a thread was not alive 
     * at the time of the interrupt will be reflected by this method 
     * returning false.
     *
     * @return <code>true</code> if the current thread has been interrupted;
     *     <code>false</code> otherwise.
     * @see #isInterrupted()
     * @revised 6.0
     */
    public static boolean interrupted() {
    return currentThread().isInterrupted(true);
    
    private native boolean isInterrupted(boolean ClearInterrupted);
    
    而如果一个线程被设置中断标识后,进行了一些处理后选择继续进行任务, 而且这个任务也是需要被中断的,那么当然需要清除标志位了。
     

    example

    org.springframework.scheduling.concurrent.ExecutorConfigurationSupport
    注意代码中Thread.currentThread().interrupt();的用法。
    	/**
    	 * Perform a shutdown on the underlying ExecutorService.
    	 * @see java.util.concurrent.ExecutorService#shutdown()
    	 * @see java.util.concurrent.ExecutorService#shutdownNow()
    	 * @see #awaitTerminationIfNecessary()
    	 */
    	public void shutdown() {
    		if (logger.isInfoEnabled()) {
    			logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
    		}
    		if (this.waitForTasksToCompleteOnShutdown) {
    			this.executor.shutdown();
    		}
    		else {
    			this.executor.shutdownNow();
    		}
    		awaitTerminationIfNecessary();
    	}
    
    	/**
    	 * Wait for the executor to terminate, according to the value of the
    	 * {@link #setAwaitTerminationSeconds "awaitTerminationSeconds"} property.
    	 */
    	private void awaitTerminationIfNecessary() {
    		if (this.awaitTerminationSeconds > 0) {
    			try {
    				if (!this.executor.awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS)) {
    					if (logger.isWarnEnabled()) {
    						logger.warn("Timed out while waiting for executor" +
    								(this.beanName != null ? " '" + this.beanName + "'" : "") + " to terminate");
    					}
    				}
    			}
    			catch (InterruptedException ex) {
    				if (logger.isWarnEnabled()) {
    					logger.warn("Interrupted while waiting for executor" +
    							(this.beanName != null ? " '" + this.beanName + "'" : "") + " to terminate");
    				}
    				Thread.currentThread().interrupt();
    			}
    		}
    	}
    
    
  • 相关阅读:
    POJ2516 构图+k次费用流
    POJ 1511 最短路径之和(spfa或dijkstra+heap)
    windows中配置mongodb
    原型设计
    Erlang的参考资源
    用Erlang实现递归查找文件
    list相关的习题
    springmvc基础知识
    汇编实验4
    实验3 转移指令跳转原理及其简单应用编程
  • 原文地址:https://www.cnblogs.com/iwangzheng/p/8807756.html
Copyright © 2011-2022 走看看