线程停止方法再次总结

有关线程停止的常用方法有这3个:

        Thread thread = new Thread(new Test());
		void thread.interrupt();
		boolean  thread.isInterrupted();
		static boolean Thread.interrupted()   or   thread.interrupted()

第一个方法是将thread对象所在的线程停止状态标示为true(true代表停止该线程)
第二个方法是判断thread对象所在的线程是否停止
第三个方法是个静态方法判断当前线程中断状态,怎么理解当前线程呢,意思是不管当前方法是哪个对象调用,它都不管,只作用在当前运行的线程上,如上面的代码如果在main方法中那么Thread.interrupted() or thread.interrupted()都是判断的是main线程是否终止 ,并且还会将标记重新设置为false,这也是唯一一个能清除线程状态的方法

网上还包括有些书本上,用volatile设置boolean变量来中断线程,虽然在某些情况下是正确的,但其实是错误的,因为如果线程被阻塞了,就算volatile被改为ture了,但是程序一直阻塞在哪里,程序依然不会停止,这种情况我会在后面说出做出说明。

上面几个方法并不像被jdk弃用的stop()方法停止线程那样干脆,调用了就停止。而是将停止线程的权利交给了线程对象本身,这样做避免了如果当前线程还有事情没有做完,如果就给它了停止了,会出现一系列不可想象的后果,特别在涉及商用,银行等方面。

而使用interrupt来停止线程还有一个重大好处就是,即使线程处于阻塞状态,被通知线程依然能够响应中断。也就是说依然可以停止。

话说怎么多 来看看具体例子:

public class Test implements Runnable {
	
	 
	public static void main(String[] args) throws InterruptedException{
		Thread thread = new Thread(new Test());
		thread.start();
		Thread.sleep(500);
		
		thread.interrupt();
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
		while(!Thread.currentThread().isInterrupted()) {
			Thread.sleep(100000000);  //模拟一个阻塞方法
		} }catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}		
	}

在这里插入图片描述
上述结果可知,因为sleep方法是个阻塞方法 ,当我们还在执行 Thread.sleep(100000000);;这行代码时, thread.interrupt();就开始通知此线程可以中断了,虽然这个线程还在休息中,但他还是被唤醒了,最终抛出一个异常,在sleep中被interrupted,最后程序还是停止了,这样就很好吧。

再看volatile 关键字情况

public class Test implements Runnable {
	private volatile static boolean flag = true;
	 
	public static void main(String[] args) throws InterruptedException{
		Thread thread = new Thread(new Test());
		thread.start();
		Thread.sleep(500);
		
		Test.flag = false;
		//thread.interrupt();
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
		while(flag) {
			Thread.sleep(100000000);  //模拟一个阻塞方法
		} }catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}		
	}

在这里插入图片描述
运行结果:可以看到程序一直在运行中,虽然我将Test.flag = false;依然没用。

最后还有个有趣的问题 try catch 位置不一样 也会影响结果 ,还是之前的代码:

public class Test implements Runnable {
	 
	public static void main(String[] args) throws InterruptedException{
		Thread thread = new Thread(new Test());
		thread.start();
		Thread.sleep(500);
		System.out.println("main休眠结束");
		thread.interrupt();
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(!Thread.currentThread().isInterrupted()) {
			try {
				System.out.println("---");
			Thread.sleep(2000);
			}catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} 
		}		
	}

结果:
在这里插入图片描述
我们将try catch 放在循环里面,抛出异常后继续打印,没有停止。
这就隐射出一种编程规法,将如你两个程序员一起编写一个项目,a程序员是编写run方法的,b程序员是写编写run方法里面调用的方法,假如a程序想要想停止这个线程,但是发现我怎么都停止不了,结果是b程序在自己写的方法里进行了try catch ,没有抛出来,这在实际项目中很难排查,所以这就是为什么异常要向上抛,抛到顶层来处理。如果你实在要处理也是有办法的。。看如下代码

public class Test implements Runnable {

	 
	public static void main(String[] args) throws InterruptedException{
		Thread thread = new Thread(new Test());
		thread.start();
		Thread.sleep(1000);
		System.out.println("main休眠结束");
		//Test.flag = false;
		thread.interrupt();
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(!Thread.currentThread().isInterrupted()) {
			a();
		} 
		}	
	
	public static void a() {
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			Thread.currentThread().interrupt();
			e.printStackTrace();
		}
	}
	}
   

如果对你有帮助,还请点个赞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值