The correct way to stop threads of a multithreaded Java

https://blog.csdn.net/trackle400/article/details/81775189
in development, often encounter the need to stop the scene of a thread running, the previous practice was stopped by Thread.stop () the specific manner It threads, but this method is now being discarded and not recommended. Not recommended for the following reasons:

1, which by the way is immediately thrown ThreadDeath exceptions to achieve the purpose of stopping the thread, and throw this exception may occur anywhere in the program, including the catch, finally, etc. statement blocks.

2, due to an exception is thrown ThreadDeatch will cause the thread to release all of the locks held, and the point in time such a release is not controlled, could lead to thread-safety issues and data inconsistencies, such as the synchronization code block the thread is abruptly stopped when performing data updates.

因此,为了避免Thread.stop()带来的问题,推荐使用被称作为Interrupt(中断)的协作机制来停止一个正在运行的线程。在JVM中,每个线程都有一个与之关联的Boolean属性,被称之为中断状态,可以通过Thread.currentThread().isInterrupted()来获取当前线程的中断状态,初始值为false。中断状态仅仅是线程的一个属性,用以表明该线程是否被中断。因为中断是线程之间的一种协作机制,因此对于被中断的线程而言,可以对中断做出响应,也可以不做任何响应(这种做法被称之为“生吞中断”,通常不建议生吞中断)。举个例子,如下代码所示:

static void main public (String [] args) {throws InterruptedException
the Thread new new the Thread T1 = (() -> {
the while (Thread.currentThread () isInterrupted ()) {!.
System.out.println ( "Hello, World") ;
}
});
t1.start ();
TimeUnit.MILLISECONDS.sleep (50);
t1.interrupt ();
}
been performing the printing operation in the thread t1 and continue polling the current thread interrupt status, to determine the current thread whether interrupted. The main thread wait 50ms, then the calling thread interrupt t1 () method set to the thread t1 interrupt status is true, the next thread polling t1 detected itself being interrupted by other threads, and thus out of the loop, the end of the thread execution. In the above code, if! Thread.currentThread (). IsInterrupted () is replaced true, that is not in the loop condition judge interrupted state of the thread, the thread t1 will always print it, will not stop, even if their own state is interrupted the main thread is set to true, that is to say the interrupted thread can respond to the interrupt, the interrupt can be ignored.

虽然在我们自己的程序中,我们可以决定要不要对中断进行响应处理,但是在Java中,有些方法已经实现了对中断的响应处理,比如Thread.sleep()、Object.wait()、BlockingQueue.put()、BlockingQueue.take()等等。当线程执行正在这些方法时,被其他线程中断掉,该线程会首先清除掉中断状态(设置中断属性为false),然后抛出InterruptedException异常。如下代码所示:

static void main public (String [] args) {throws InterruptedException
the Thread new new the Thread T1 = (() -> {
the try {
System.out.println ( "initial thread interrupt status ->" + Thread.currentThread () isInterrupted (). );
the Thread.sleep (10000);
} the catch (InterruptedException E) {
System.out.println ( "exception is thrown after thread interrupt status ->" + Thread.currentThread () isInterrupted ());.
e.printStackTrace () ;
}
});
t1.start ();
TimeUnit.MILLISECONDS.sleep (50);
t1.interrupt ();
}
run results are shown below:

在平时代码中对中断的处理,不推荐生吞中断,通常有这两种做法:抛出中断异常、上传中断状态。对于抛出中断异常这种做法,也就是Thread.sleep()的这种做法。但是在某些情况下,抛出中断异常并不合适或者不能上抛异常,比如在Runnable定义的任务中,不能对外抛出异常,必须要在代码里处理掉异常。这种情况下,最好的做法就是上传中断状态,保留中断发生的证据,以便调用栈中更高层的代码能够知道发生了中断,并对中断做出响应。具体代码如下所示:

TaskRunner class the implements the Runnable {public
@Override
public void RUN () {
the try {
// TODO ...
the Thread.sleep (1000);
// TODO ...
} the catch (InterruptedException E) {
e.printStackTrace ();
// interrupt status in throwing before the abnormality is removed, so here to reset the interrupt status
Thread.currentThread () interrupt ();.
}
}
}

as compared to the terminated thread are Thread.stop by (), using an interrupt mechanism to stop the cooperative threads the approach allows the program to control himself in the right place to release their locks held, and the completion of related clean-up work before the thread exits, of course, the program can also choose to ignore the interruption and continue to run. In short, compared to Thread.stop () at any time and any place are likely to immediately stop the thread, the adoption of this way to interrupt the interrupted thread and related follow-up operations are handed over to exit the program to control the process, more controllable .

Difference Thread.interrupted () and Thread.currentThread () isInterrupted (): The final add.

FIG Thread.interrupted () follows to realize source

FIG Thread.currentThread (). IsInterrupted () follows to realize source

I can see that two are called Thread object isInterrupted (boolean ClearInterrupted) method, which is a native method.

You can see by the code, Thread.interrupted () is to obtain and clears the interrupt status of the current thread, Thread.currentThread (). IsInterrupted () just get the current thread's interrupt status is not clear the interrupt status of the current thread.

Guess you like

Origin blog.csdn.net/qq_35577329/article/details/89948976