java中断小记
java中与中断相关的函数有如下三个:
1.通过成员方法Thread.interrupt()来设置中断状态为true
2.通过成员方法Thread.isInterrupted()来获取中断状态
3.通过静态方法Thread.interrupted()来获取中断状态,并且清除中断状态(当然获取的是清除之前的值),也就是说连续两次调用此方法,第二次一定会返回false。
下面详细介绍各个方法。
成员方法new Thread().interrupt()
线程的成员方法new Thread().interrupt()是中断线程,设置该线程的中断状态位,即设置为true(默认为false),中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法(很少用stop来结束线程,用共享变量或者别的方法实现线程的结束)那样会中断一个正在运行的线程。
但是interrupt()方法并不能中断正在运行(有关线程状态请参考http://yimaoqian.blog.51cto.com/1328422/1399767这篇博文)的线程,程序实例如下:
- public class TestSun {
- public static void main(String[] args){
- // test1
- Thread t1 = new Thread(){
- @Override
- public void run(){
- try{
- int i=0;
- while(i++<100000000){
- // nothing
- }
- System.out.println("A1");
- }catch(Exception e){
- System.out.println("B1");
- };
- };
- t1.start();
- System.out.println(t1.isInterrupted() + " before");//查看线程是否中断(中断标志位)
- t1.interrupt();//不中断正在运行的线程
- System.out.println(t1.isInterrupted() + " after");
- }
- }
- ---------------------------
- 运行结果:
- false before
- true after
- A1
由运行结果分析出t1.interrupt()并没有中断线程t1,即得出结论成员方法interrupt()方法对正在运行的方法(即没有阻塞)不起作用,只对处于阻塞中的线程起作用。
interrupt()方法中断处于阻塞状态(此处的阻塞状态不包括因IO操作引起的阻塞,只包括wait、join、sleep)的线程时,会抛出InterruptedException异常,并且将中断状态被清除(即将调用interrupt()方法时设置的true清除,变为false),程序实例:
- public class TestSun {
- public static void main(String[] args){
- // test1
- Thread t1 = new Thread(){
- @Override
- public void run(){
- try{
- int i=0;
- while(i++<100000000){
- // nothing
- }
- System.out.println("A1");
- Thread.sleep(5000);//阻塞线程
- }catch(Exception e){
- System.out.println("B1");
- //抛出异常之后中断标志位才清除
- System.out.println(Thread.currentThread().isInterrupted() + " in catch");
- }
- };
- };
- t1.start();
- System.out.println(t1.isInterrupted() + " before");
- t1.interrupt();//不中断正在运行的线程
- System.out.println(t1.isInterrupted() + " after");
- }
- }
- --------------------------------------------
- 运行结果:
- false before
- true after
- A1
- B1
- false in catch
上面说到interrupt()方法无法中断因IO操作引起的阻塞的线程,这里用一个程序说明下:
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- public class Exemple4 extends Thread {
- public static void main( String args[] ) throws Exception {
- Exemple4 thread = new Exemple4();
- 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..." );
- }
- public void run() {
- ServerSocket socket;
- try { www.xiaoxiongboke.com/
- 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..." );
- }
- }
- }
- }
- -------------------------------------------
- 运行结果:
- Starting thread...
- Waiting for connection...
- Interrupting thread...
- Stopping application...
其实interrupt()方法还不能中断死锁状态的线程,因为锁定的位置根本无法抛出异常,程序示例:
- public class Exemple4 extends Thread {
- public static void main(String args[]) throws Exception {
- final Object lock1 = new Object();
- final Object lock2 = new Object();
- Thread thread1 = new Thread() {
- public void run() {
- deathLock(lock1, lock2);
- }
- };
- Thread thread2 = new Thread() {
- public void run() {
- // 注意,这里在交换了一下位置
- deathLock(lock2, lock1);
- }
- };
- System.out.println("Starting thread...");
- thread1.start();
- thread2.start();
- Thread.sleep(3000);
- System.out.println("Interrupting thread...");
- thread1.interrupt();
- thread2.interrupt();
- Thread.sleep(3000);
- System.out.println("Stopping application...");
- }
- static void deathLock(Object lock1, Object lock2) {
- try {
- synchronized (lock1) {
- Thread.sleep(10);// 不会在这里死掉
- // System.out.println(lock1 + " thread...");
- synchronized (lock2) {// 会锁在这里,虽然阻塞了,但不会抛异常
- System.out.println(Thread.currentThread());
- }
- }
- } catch (InterruptedException e) {
- System.out.println("exception thread...");
- e.printStackTrace();
- System.exit(1);
- }
- }
- ----------------------
- 运行结果:
- Starting thread...
- Interrupting thread...
- Stopping application...
当不发生死锁时,线程可以正常中断,程序实例:
- Thread t4 = new Thread(){
- public void run(){
- try{
- synchronized(this){
- this.wait(50000);
- }
- System.out.println("A4");
- }catch(Exception e){
- System.out.println("B4");
- }
- };
- };
- t4.start();
- t4.interrupt(); //可以中断是因为没有发生竞争上锁
- ----------------------------
- 运行结果:
- B4
2.成员方法new Thread().isInterrupted()
要熄灯了,先写到这里,有时间再继续.