java中有三种停止线程方法
1)使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2)使用stop方法方法强行终止线程,但是不推荐使用这个方法,应为stop不安全而且已经被废弃的方法,还有suspend和resume都是废弃的方法。
3)使用interrupt方法中断线程。
讲解第三种interrupt()方法 仅仅使房钱线程中打了一个停止的标记,并不是真的停止线程。代码如下:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { System.out.println("i=" + (i + 1)); } } }
public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } } }
线程没有停止,而是打印完i
再分析下线程是否是停止的状态
this.interrupted() 测试当前线程是否已经中断。
this.isInterrupted()测试线程是否已经中断。
两者区别:(小白还是不懂,如果大神们知道还请您给我留个言解答下☺)
如下代码展示:
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 50000; i++) { System.out.println("i=" + (i + 1)); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); //Thread.currentThread().interrupt(); System.out.println(thread.getName()+ " 是否停止1?="+thread.interrupted()); System.out.println(thread.getName()+ " 是否停止2?="+thread.interrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } public class Run2 { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); Thread.currentThread().interrupt(); System.out.println("是否停止1?=" + Thread.interrupted()); System.out.println("是否停止2?=" + Thread.interrupted()); System.out.println("end!"); } } public class Run3 { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println("是否停止1?="+thread.isInterrupted()); System.out.println("是否停止2?="+thread.isInterrupted()); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
结果图:
1:停止线程(异常法)
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { if (this.interrupted()) { System.out.println("已经是停止状态了!我要退出了!"); break; } System.out.println("i=" + (i + 1)); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); thread.sleep(2000);//线程睡2s 停止 // Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
上面的代码会出现下面问题:并没有真正的退出线程
public class MyThread extends Thread { @Override public void run() { super.run(); for (int i = 0; i < 500000; i++) { if (this.interrupted()) { System.out.println("已经是停止状态了!我要退出了!"); break; } System.out.println("i=" + (i + 1)); } System.out.println("我被输出,如果此代码是for又继续运行,线程并未停止!"); } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
解决如下
public class MyThread extends Thread { @Override public void run() { super.run(); try { for (int i = 0; i < 500000; i++) { if (this.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(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(2000); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
2:在沉睡中停止线程
public class MyThread extends Thread { @Override public void run() { super.run(); try { System.out.println("run begin"); Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止!进入catch!"+this.isInterrupted()); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.start(); Thread.sleep(200); thread.interrupt(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } System.out.println("end!"); } }
下面是先停止线程 再遇到sleep进入catch
public class MyThread extends Thread { @Override public void run() { super.run(); try { for(int i=0;i<100000;i++){ System.out.println("i="+(i+1)); } System.out.println("run begin"); Thread.sleep(20000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("先停止,再遇到了sleep!进入catch!"); e.printStackTrace(); } } } public class Run { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); thread.interrupt(); System.out.println("end!"); } }
3:使用stop()暴力停止线程。。会释放当前对象持有的锁
public class SynchronizedObject { private String username = "a"; private String password = "aa"; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } //注意这里加同步方法 但是由于使用了stop方法 是对象释放锁 synchronized public void printString(String username, String password) { try { this.username = username; Thread.sleep(100000); this.password = password; } catch (InterruptedException e) { e.printStackTrace(); } } } public class MyThread extends Thread { private SynchronizedObject object; public MyThread(SynchronizedObject object) { super(); this.object = object; } @Override public void run() { object.printString("b", "bb"); } } public class Run { public static void main(String[] args) { try { SynchronizedObject object = new SynchronizedObject(); MyThread thread = new MyThread(object); thread.start(); Thread.sleep(500); thread.stop(); System.out.println(object.getUsername() + " " + object.getPassword()); } catch (InterruptedException e) { e.printStackTrace(); } } }打印如下