多线程(1)-线程的终止方法

前言

       近期看了一本关于多线程的书籍《Java多线程编程核心技术》。下面对学习到的关于线程的终止方法进行总结,如果有错误欢迎大家指出,如果对大家有帮助,欢迎转载和点赞。

概述

     java中有三中方法终止正在运行的线程:

     (1)、通过推退出标志,使线程正常退出,也就是当run方法完成后终止。

     (2)、通过Thead.stop()方法强行终止线程,但是不推荐这么使用,因为此方法是不安全的,已经作废过期。

     (3)、调用interrupt方法终止线程。

stop方法终止线程

     调用stop方法后会马上终止正在运行的线程,这样强制终止线程,有可能会导致有些清理工作得不到完成,还有种情况是对锁定的数据进行了解锁,导致数据得不到同步处理,导致数据出现不一致。

    下面以一个例子进行介绍。

package thread.stop;
/***
 * 用于线程stop方法中断流程例子演示
 * @author swh
 *
 */
public class ThreadStopTest extends Thread {

	public void run() {
		int i = 0;
		try {
			while( true ) {
				i++;
				System.out.println(i);
				Thread.sleep(1000L);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String args[]) {
		try {
			ThreadStopTest thread = new ThreadStopTest();
			thread.start();
			Thread.sleep(5000L);
			thread.stop();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

上面的代码比较简单,及时在main 线程中启动一个ThreadStopTest线程,然后休眠5秒,ThreadStopTest线程就是循环输出i,输出一次后休眠一秒,当ThreadStopTest循环运行5次main线程醒来,通过stop方法强制中断线程。下面是运行的结果。

现在以一个简单的例子来介绍下用stop方法中断线程会导致的问题。

package thread.stop;
/***
 * 用于演示线程stop方法会导致的安全问题
 * @author swh
 *
 */
public class SafeStopThread implements Runnable {

	private int i =0;
	@Override
	public void run() {
		synchronized("") {
			i++;
			try {
				Thread.sleep(1000L);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			i--;
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
	public static void main(String args[]) {
		 Thread thread=new Thread(new SafeStopThread());
		 thread.start();
		 for(int i =0;i<5;i++) {
			 new Thread(thread).start();
		 }
		 thread.stop();
	}

}

      其中i是几个线程公用的变量,其中run方法中加上了 synchronized 代码块,表示内部是原子逻辑,它会先自增然后再自减少,按照synchronized同步代码块的规 则来处理,此时无论启动多少个线程,打印出来的结果都应该是a=0,但是如果有一个正在执 行的线程被stop,就会破坏这种原子逻辑。下面是运行的结果。

interrupt方法终止线程

     interrupt方法并不像stop方法那样强制中断一个线程,而是给线程打上一个中断标志,并不是真的中断线程。这里先需要先介绍下两个方法。

interrupted();测试当前线程是否已经中断。此方法调用后会重置中断标志,即第一调用如果为true后会重置为false;

  public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

isinertrupted();测试线程是否已经中断。

  public boolean isInterrupted() {
        return isInterrupted(false);
    }

调用interrupt中断线程例子如下,我们可以调用上面两个方法来得到中断标志来判断,来解决逻辑的原子性被破坏的问题;

package thread.interrupt;

/***
 * 流程中断
 * @author swh
 *
 */
public class InertruptThread extends Thread {

	public void run() {
		
		int i = 0;
		try {
			while(!this.isInterrupted()) {
				i++;
				System.out.println(i);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	public static void main(String args[]) {
		try {
			InertruptThread  inertruptThread = new InertruptThread();
			inertruptThread.start();;
			Thread.sleep(10L);
			inertruptThread.interrupt();;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}

运行后得结果:

猜你喜欢

转载自blog.csdn.net/swh1314/article/details/81106826