Java 停止线程
停止java线程有三种常见的方式:
- 使用退出标志,使线程正常退出,也就是run方法完成时后线程停止。
- 使用stop线程强行终止线程,但是不推荐这种暴力停止的方法,会导致很多难以估计的错误与异常,比如最常见的数据不一致的错误。
- 使用interrupt方法中断线程
interrup停止线程——不能停止的线程
使用interrupt方法并不能像for+break那样,马上优雅的停止循环,而是在当前线程打了一个停止标记而已,并不能终止线程。
public class App {
public static void main(String[] args) throws Exception {
run run=new run();
run.start();
Thread.sleep(2000);
run.interrupt();
System.out.println(run.interrupted());
}
}
public class run extends Thread{
@Override
public void run()
{
for(int i=0;i<500000;i++){
System.out.println("i="+i);
}
}
}
从运行结果来看线程并未停止。
interrupted()和isInterrupted()方法
两个方法的声明:
public static boolean interrupted()
public boolean isInterrupted()
public class run extends Thread{
@Override
public void run()
{
for(int i=0;i<500000;i++){
System.out.println("i="+i);
}
}
}
public class App {
public static void main(String[] args) throws Exception {
run run=new run();
run.start();
Thread.sleep(2000);
run.interrupt();
//Thread.currentThread().interrupt();
System.out.println("1."+run.interrupted());
System.out.println("2."+run.interrupted());
}
}
首先interrupted()和isInterrupted()方法都是探测this线程是否已经中断,如果中断则为true,反正则为false。那么interrupted()和isInterrupted()方法有什么区别呢?请看如下两段代码:
public class App {
public static void main(String[] args) throws Exception {
Thread.currentThread().interrupt();//使main线程产生中断效果
System.out.println("1."+Thread.interrupted());
System.out.println("2."+Thread.interrupted());
}
}
可以看到第一次interrupted()为true,已经产生了中断效果,第二interrupted()竟然变成了false。
因为this.interrupted()方法不管能探测当前线程是否中断,执行后还能将状态标志清除。
public class run extends Thread{
@Override
public void run()
{
for(int i=0;i<500000;i++){
System.out.println("i="+i);
}
}
}
public class App {
public static void main(String[] args) throws Exception {
run run=new run();
run.start();
Thread.sleep(2000);
run.interrupt();
System.out.println("1."+run.isInterrupted());
System.out.println("2."+run.isInterrupted());
}
}
可以看出isInterrupted()方法,并未清除中断标志。
isInterrupted()方法测试Thread对象是否为中断状态。
interrup()——异常法停止线程
public class run extends Thread{
@Override
public void run()
{
try{
for(int i=0;i<500000000;i++){
if(this.interrupted()){
System.out.println("线程退出");
throw new InterruptedException();
//break;
}
System.out.println("i="+i);
}
System.out.println("线程并未停止");
}catch(InterruptedException e){
System.out.println("进入catch");
e.printStackTrace();
}
}
}
public class App {
public static void main(String[] args) throws Exception {
run run=new run();
run.start();
Thread.sleep(2000);
run.interrupt();
System.out.println(run.interrupted());
}
}
由此看出运用异常,线程已经退出。
睡眠中停止
public class run extends Thread{
@Override
public void run(){
try{
System.out.println("run begin");
Thread.sleep(2000000);
System.out.println("run end");
}catch(InterruptedException e){
System.out.println("进入catch");
e.printStackTrace();
}
}
}
public class App {
public static void main(String[] args) throws Exception {
run run=new run();
run.start();
Thread.sleep(2000);
run.interrupt();
//System.out.println(run.interrupted());
}
}
如果在sleep停止线程,就会引入catch语句,并且清除停止状态值。
不推荐的stop()暴力停止
public class User {
private String username="a";
private String password="aa";
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
synchronized public void printString(String name,String passwd){
try{
setUsername(name);
Thread.sleep(100000);
setPassword(passwd);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public class MyThread extends Thread{
private User user;
public MyThread(User user){
this.user=user;
}
@Override
public void run(){
user.printString("b", "bb");
}
}
public class App {
public static void main(String[] args) throws Exception {
try{
User user=new User();
MyThread thread=new MyThread(user);
thread.start();
Thread.sleep(500);
thread.stop();
System.out.println(user.getUsername()+" "+user.getPassword());
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
可以看出stop()暴力停止的方式,使程序数据遭到了破坏,导致了数据不一致的现象。
return停止法
public class run extends Thread{
@Override
public void run()
{
while(true){
if(this.isInterrupted()){
System.out.println("线程停止!");
return;
}
System.out.println("time="+System.currentTimeMillis());
}
}
}
public class App {
public static void main(String[] args) throws Exception {
run run=new run();
run.start();
Thread.sleep(2000);
run.interrupt();
}
}