程序是很简易的。然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,
将导致意外的行为以及细微的、难以发现的错误。
在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程。
背景
中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作。线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序。虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果。你最好还是牢记以下的几点告诫。
首先,忘掉Thread.stop方法。虽然它确实停止了一个正在运行的线程,然而,这种方法是不安全也是不受提倡的,这意味着,在未来的JAVA版本中,它将不复存在。
一些轻率的家伙可能被另一种方法Thread.interrupt所迷惑。尽管,其名称似乎在暗示着什么,然而,这种方法并不会中断一个正在运行的线程(待会将进一步说明),正如Listing A中描述的那样。它创建了一个线程,并且试图使用Thread.interrupt方法停止该线程。Thread.sleep()方法的调用,为线程的初始化和中止提供了充裕的时间。线程本身并不参与任何有用的操作。
Listing A
-
class Example1 extends Thread {
-
boolean stop=
false;
-
public static void main( String args[] ) throws Exception {
-
Example1 thread =
new Example1();
-
System.out.println(
“Starting thread…” );
-
thread.start();
-
Thread.sleep(
3000 );
-
System.out.println(
“Interrupting thread…” );
-
thread.interrupt();
-
Thread.sleep(
3000 );
-
System.out.println(
“Stopping application…” );
-
//System.exit(0);
-
}
-
public void run() {
-
while(!stop){
-
System.out.println(
“Thread is running…” );
-
long time = System.currentTimeMillis();
-
while((System.currentTimeMillis()-time <
1000)) {
-
}
-
}
-
System.out.println(
“Thread exiting under request…” );
-
}
-
}
如果你运行了Listing A中的代码,你将在控制台看到以下输出:
中断线程最好的,最受推荐的方式是,使用共享变量(shared variable)发出信号,告诉线程必须停止正在运行的任务。
线程必须周期性的核查这一变量(尤其在冗余操作期间),然后有秩序地中止任务。Listing B描述了这一方式。
-
class Example2 extends Thread {
-
volatile
boolean stop =
false;
-
public static void main( String args[] ) throws Exception {
-
Example2 thread =
new Example2();
-
System.out.println(
"Starting thread..." );
-
thread.start();
-
Thread.sleep(
3000 );
-
System.out.println(
"Asking thread to stop..." );
-
-
thread.stop =
true;
-
Thread.sleep(
3000 );
-
System.out.println(
"Stopping application..." );
-
//System.exit( 0 );
-
}
-
-
public void run() {
-
while ( !stop ) {
-
System.out.println(
"Thread is running..." );
-
long time = System.currentTimeMillis();
-
while ( (System.currentTimeMillis()-time <
1000) && (!stop) ) {
-
}
-
}
-
System.out.println(
"Thread exiting under request..." );
-
}
-
}
-
class Example3 extends Thread {
-
volatile
boolean stop =
false;
-
public static void main( String args[] ) throws Exception {
-
Example3 thread =
new Example3();
-
System.out.println(
"Starting thread..." );
-
thread.start();
-
Thread.sleep(
3000 );
-
System.out.println(
"Asking thread to stop..." );
-
thread.stop =
true;
//如果线程阻塞,将不会检查此变量
-
thread.interrupt();
-
Thread.sleep(
3000 );
-
System.out.println(
"Stopping application..." );
-
//System.exit( 0 );
-
}
-
-
public void run() {
-
while ( !stop ) {
-
System.out.println(
"Thread running..." );
-
try {
-
Thread.sleep(
1000 );
-
}
catch ( InterruptedException e ) {
-
System.out.println(
"Thread interrupted..." );
-
}
-
}
-
System.out.println(
"Thread exiting under request..." );
-
}
-
}
-
import java.io.*;
-
class Example4 extends Thread {
-
public static void main( String args[] ) throws Exception {
-
Example4 thread =
new Example4();
-
System.out.println(
"Starting thread..." );
-
thread.start();
-
Thread.sleep(
3000 );
-
System.out.println(
"Interrupting thread..." );
-
thread.interrupt();
-
Thread.sleep(
3000 );
-
System.out.println(
"Stopping application..." );
-
//System.exit( 0 );
-
}
-
-
public void run() {
-
ServerSocket socket;
-
try {
-
socket =
new ServerSocket(
7856);
-
}
catch ( IOException e ) {
-
System.out.println(
"Could not create the socket..." );
-
return;
-
}
-
while (
true ) {
-
System.out.println(
"Waiting for connection..." );
-
try {
-
Socket sock = socket.accept();
-
}
catch ( IOException e ) {
-
System.out.println(
"accept() failed or interrupted..." );
-
}
-
}
-
}
-
}
-
import java.net.*;
-
import java.io.*;
-
class Example5 extends Thread {
-
volatile
boolean stop =
false;
-
volatile ServerSocket socket;
-
public static void main( String args[] ) throws Exception {
-
Example5 thread =
new Example5();
-
System.out.println(
"Starting thread..." );
-
thread.start();
-
Thread.sleep(
3000 );
-
System.out.println(
"Asking thread to stop..." );
-
thread.stop =
true;
-
thread.socket.close();
-
Thread.sleep(
3000 );
-
System.out.println(
"Stopping application..." );
-
//System.exit( 0 );
-
}
-
public void run() {
-
try {
-
socket =
new ServerSocket(
7856);
-
}
catch ( IOException e ) {
-
System.out.println(
"Could not create the socket..." );
-
return;
-
}
-
while ( !stop ) {
-
System.out.println(
"Waiting for connection..." );
-
try {
-
Socket sock = socket.accept();
-
}
catch ( IOException e ) {
-
System.out.println(
"accept() failed or interrupted..." );
-
}
-
}
-
System.out.println(
"Thread exiting under request..." );
-
}
-
}