停止线程 & 暂停线程

停止线程

停止一个线程意味着在线程处理完任务之前停止正在进行的操作,即放弃当前的操作。
Java中有以下3中方法可以终止正在运行的线程:

  1. 使用退出标志,使线程正常退出(当run方法完成后线程终止)
  2. 使用stop方法强行终止线程 (作废的方法,不安全)
  3. 使用interrupt方法中断线程

interrupt()方法不会马上停止线程,仅仅是在当前线程中打下停止标记。

package stopthread;

public class MyThread extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		for(int i = 0; i < 500000; i++) {
			System.out.println("i=" + (i+1));
		}
	}
}
package stopthread;

public class Run {
	public static void main(String[] args) {
		try {
			MyThread mythread = new MyThread();
			mythread.start();
			Thread.sleep(2000);
			mythread.interrupt();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("main catch");
			e.printStackTrace();
		}
		
	}
}

运行结果:
在这里插入图片描述
线程并没有停止,interrupt()应以什么姿势使用呢?
首先,我们需要知道如何判断线程的状态是否是停止的,Java的JDK中,Thread.java类里提供了两种方法:

  1. this.interrupted():测试当前线程是否中断(当前,指运行this.interrupted()的线程)——static方法
  2. this.isInterrupted():测试线程是否中断——非static

要注意,interrupted()方法连续使用两次,第一次返回true,第二次返回false,官方帮助文档的解释为:

测试当前线程是否已经中断。线程的中断状态由该方法清除。

也就是interrupted()执行后具有将状态标志清除为false的功能,而isInterrupted()不清除状态标志。

停止线程的方法
1. 异常法

以抛出异常的方法停止线程。

package stopthread;

public class ExitThread extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		try {
			for(int i = 0; i<500000; i++) {
				if(ExitThread.interrupted()) {
					System.out.println("已经是终止状态!我要退出!");
					throw new InterruptedException();
				}
				System.out.println("i=" + (i+1));
			}
			System.out.println("我在for下面");
		}catch(InterruptedException e) {
			System.out.println("进入MyThread.java类run方法中的catch了!");
			e.printStackTrace();
		}
	}
}
package stopthread;

public class Run {
	public static void main(String[] args) {
		try {
			ExitThread mythread = new ExitThread();
			mythread.start();
			Thread.sleep(1000);
			mythread.interrupt();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("main catch");
			e.printStackTrace();
		}
	}
}

运行结果:
在这里插入图片描述

2. sleep状态下停止线程

sleep状态下停止线程会有怎样的效果呢?
如果先终止线程,再sleep呢?

package stopthread;

public class SleepExitThread extends Thread{
	@Override
	public void run() {
		super.run();
		try {
			System.out.println("run begin");
			Thread.sleep(200000);  //处于睡眠状态,main方法中停止此线程发生异常,进入catch
			System.out.println("run end");
		}catch(InterruptedException e) {
			System.out.println("在沉睡中被停止,进入catch!" + this.isInterrupted());
			e.printStackTrace();
		}
	}
}
package stopthread;

public class Run {
	public static void main(String[] args) {
		try {
			SleepExitThread mythread = new SleepExitThread();
			mythread.start();
			Thread.sleep(200);
			mythread.interrupt();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("main catch");
			e.printStackTrace();
		}
	}
}

运行结果:
在这里插入图片描述
如果在sleep状态下停止某一线程,会进入catch,并且清除停止状态,使之变为false。

先interrupt()再sleep是什么样的效果呢?

package stopthread;

public class MyThread extends Thread{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		try {
			for(int i = 0; i < 500000; i++) {
				System.out.println("i=" + (i+1));
			}
			System.out.println("run begin");
			Thread.sleep(200000);
			System.out.println("run end");
		}catch(InterruptedException e) {
			System.out.println("先停止,再遇到了sleep!进入catch!");
			e.printStackTrace();
		}
	}
}
package stopthread;

public class Run {
	public static void main(String[] args) {
		MyThread mythread = new MyThread();
		mythread.start();
		mythread.interrupt();
		System.out.println("end!");
	}
}

运行结果:
在这里插入图片描述

3. 使用return停止线程 (不推荐)

interrupt()与return结合使用也能实现停止线程。

package stopthread;

public class UseReturnExitThread extends Thread{
	@Override
	public void run() {
		while(true) {
			if(this.isInterrupted()) {
				System.out.println("停止了!");
				return;
			}
			System.out.println("timer=" + System.currentTimeMillis());
		}
	}
}
package stopthread;

public class Run {
	public static void main(String[] args) throws InterruptedException {
		UseReturnExitThread mythread = new UseReturnExitThread();
		mythread.start();
		Thread.sleep(2000);
		mythread.interrupt();
	}
}

运行结果:
在这里插入图片描述
建议使用“异常法”,因为在catch块中可以对异常信息进行相关的处理,而且使用异常流能更好地控制程序的运行流程,不至于出现多个return;造成污染。

暂停线程

未完待续

Reference

高洪岩 《Java多线程编程核心技术》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线程是指在一个进程内,执行没有被调度程序轮流执行的一段指令的单个线程线程可以是扮演多种角色的工作流程的一员,这种工作流程被称为多线程应用程序。多线程应用程序允许多个程序同时执行,该应用程序的每个线程都可以在不同的时间间隔内运行,并且在执行过程可以对其进行暂停、继续、停止等操作。 暂停线程是指停止线程执行,直到另一个线程继续它。线程可能会被暂停以等待外部资源,也可以通过暂停来完成多任务处理。在一个多线程应用程序,可以暂停单个线程,而不影响应用程序的整体执行线程暂停操作可以通过调用Thread类的sleep()方法或wait()方法来实现。当线程暂停时,它的CPU时间分配将被释放,因此,就可以同时执行其他线程。 继续线程是指在线程暂停后,再次开始执行线程线程可以在任何时候被暂停,然后在稍后的时间点继续执行。在Java线程可以通过调用Thread类的synchronized()方法来实现继续。在多线程应用程序线程可以通过被唤醒或获取锁来继续执行停止线程是指使线程不再继续执行,即完成线程的生命周期。线程可以通过Java的stop()方法或interrupt()方法来停止。当线程停止时,它将无法再次启动,并且与系统的资源将被释放。停止线程应该是有策略的,以便在完成线程任务以后释放线程资源。如果没有任何策略,那么应用程序多线程可能会导致线程冲突、错误或死锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值