Java基础技术

Java 线程中断与睡眠

2017-02-04  本文已影响177人  酱油和醋
1.sleep 让线程睡眠
    /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds plus the specified
     * number of nanoseconds, subject to the precision and accuracy of system
     * timers and schedulers. The thread does not lose ownership of any
     * monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @param  nanos
     *         {@code 0-999999} additional nanoseconds to sleep
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative, or the value of
     *          {@code nanos} is not in the range {@code 0-999999}
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }
     /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;

通过源码可以看出,最终sleep的时间粒度是毫秒数,虽然第一个方法存在有纳秒级的参数,但是如果纳秒超过500000才会加一毫秒,否则毫秒数没有变化。</br>

2.interrupt 发送中断请求

线程终止的时间:1.当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时;2.出现了方法中没有捕获的异常时。 并没有强制线程终止的方法,interrupt方法可以用来请求 终止线程。
当对一个线程调用interrupt方法时,线程的中断状态将被置位</br>

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(this);
                return;
            }
        }
        interrupt0();
    }

1.如果该线程正阻塞于Object类的wait()、wait(long)、wait(long, int)方法,或者Thread类的join()、join(long)、join(long, int)、sleep(long)、sleep(long, int)方法,则该线程的中断状态将被清除,并收到一个java.lang.InterruptedException。
2.如果该线程正阻塞于interruptible channel上的I/O操作,则该通道将被关闭,同时该线程的中断状态被设置,并收到一个java.nio.channels.ClosedByInterruptException。</br>
3.如果该线程正阻塞于一个java.nio.channels.Selector操作,则该线程的中断状态被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用java.nio.channels.Selector.wakeup()方法一样。</br>
4.如果上述条件都不成立,则该线程的中断状态将被设置。</p>
调用了interrupt方法时,阻塞调用将会被interruptException异常中断。</br>

public class ThreadTest {
    @Test
    public void threadRunTest() {
        Thread thread = new Thread() {
            public void run() {
                try {
                    for (int i = 0; i < 1000; i++) {
                        Thread.sleep(500);
                        System.out.println(i);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        thread.start();
        try {
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
    }
}

运行结果:

线程运行结果.png

Java多线程之interrupt()的深度研究
申请中断的线程被阻塞时,会抛出InterruptionException

public class PendingInterrupt extends Object {  
    public static void main(String[] args){  
        //如果输入了参数,则在mian线程中中断当前线程(亦即main线程)  
        if( args.length > 0 ){  
            Thread.currentThread().interrupt();  
        }   
        //获取当前时间  
        long startTime = System.currentTimeMillis();  
        try{  
            Thread.sleep(2000);  
            System.out.println("was NOT interrupted");  
        }catch(InterruptedException x){  
            System.out.println("was interrupted");  
        }  
        //计算中间代码执行的时间  
        System.out.println("elapsedTime=" + ( System.currentTimeMillis() - startTime));  
    }  
}

运行结果

线程运行结果2.png
3.isInterrupt测试线程是否中断

如果想知道线程的中断状态是否被置位,可以调用

/**
     * 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);
    }

这个方法不会改变线程的中断状态。

4.interrupted 检测线程中断的状态并将线程的中断状态重置为false
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }
    private native boolean isInterrupted(boolean ClearInterrupted);
上一篇下一篇

猜你喜欢

热点阅读