Java 线程中断与睡眠
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();
}
}
运行结果:
线程运行结果.pngJava多线程之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.png3.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);