停止线程:
interrupt()方法停止线程
this.interrupted() 测试当前的线程是否处于中断状态,并会将状态标志清除为false。
this.isInterrupted() 测试thread线程是否处于中断状态,不会去改变状态。
在沉睡中停止:
在sleep状态下停止线程:结果是会进入catch语句,并且会将停止状态置为false
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 MyThread1 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(200000); System.out.println("run end"); } catch (Exception e) { System.out.println("先停止,再遇到sleep 进入catch"); e.printStackTrace(); } } } public class Run1 { public static void main(String[] args) { MyThread1 thread1=new MyThread1(); thread1.start(); thread1.interrupt(); System.out.println("end!"); } }
stop 暴力停止线程,可以停止,但是可能会造成一些不可预期的后果,已经废止,不建议使用 后果是:1,一些清理工作没有完成 2,可能会对一些加锁的对象进行解锁,造成数据的不同步
stop 方法会进入threadDath异常
public class MyThread extends Thread{ private int i=0; @Override public void run() { try { while (true) { i++; System.out.println("i="+i); Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } } public class Run { public static void main(String[] args) { try { MyThread thread=new MyThread(); thread.start(); Thread.sleep(8000); thread.stop(); } catch (InterruptedException e) { e.printStackTrace(); } } }
调用stop方法停止线程,对加锁的对象进行了解锁,造成数据不同步的例子
public class SynchronizedObject { private String userName="a"; private String password="aa"; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUserName() { return userName; } public void setUseName(String userName) { this.userName=userName; } // 这个方法加锁后,本来userName和password要么都被赋予新值,要么都未被赋值 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();//在调用stop方法后将锁给解锁了,造成数据不一致 System.out.println(object.getUserName()+" "+object.getPassword());//前者被赋值了,而后者没有 结果是 b aa } catch (InterruptedException e) { e.printStackTrace(); } } }
采用interupt方法和return来停止线程
public class MyThread extends Thread{ @Override public void run() { while (true) { if(this.isInterrupted()) {//检查中断状态 System.out.println("停止了"); return; //若中断状态为true则结束线程,返回达到线程停止的目的 } System.out.println("timer="+System.currentTimeMillis()); } } } public class Run { public static void main(String[] args){ try { MyThread thread=new MyThread(); thread.start(); Thread.sleep(200); thread.interrupt();//调用中断线程的方法 } catch (InterruptedException e) { e.printStackTrace(); } } }
暂停线程:
采用suspend和resume方法可以暂停线程和使线程重新恢复运行
public class MyThread extends Thread{ private long i=0; public long getI() { return i; } public void setI(long i) { this.i = i; } @Override public void run() { while (true) { i++; } } } public class Run { public static void main(String[] args) { try { MyThread thread =new MyThread(); thread.start(); Thread.sleep(5000); thread.suspend();//暂停线程 System.out.println("A="+System.currentTimeMillis()+"i="+thread.getI()); Thread.sleep(5000); System.out.println("A="+System.currentTimeMillis()+"i="+thread.getI()); thread.resume();//使线程重新恢复运行 Thread.sleep(5000); System.out.println("B="+System.currentTimeMillis()+"i="+thread.getI()); Thread.sleep(5000); System.out.println("B="+System.currentTimeMillis()+"i="+thread.getI()); } catch (InterruptedException e) { e.printStackTrace(); } } /*A=1550371225618i=3775194690 A=1550371230629i=3775194690 B=1550371235630i=7719710287 B=1550371240642i=11697485852*/ }
使用suspend方法可能会造成公共同步对象的强占,而其他线程无法使用。
public class SynchrinizedObject { synchronized public void printString() { System.out.println("begin"); if(Thread.currentThread().getName().equals("a")) { System.out.println("a线程永远suspend 了"); Thread.currentThread().suspend(); } System.out.println("end"); } } public class Run { public static void main(String[] args) { try { final SynchrinizedObject object=new SynchrinizedObject(); Thread thread=new Thread() { @Override public void run() { object.printString(); } }; thread.setName("a"); thread.start(); thread.sleep(1000); Thread thread2=new Thread() { @Override public void run() { System.out.println("..............."); //线程2可以启动运行,但是进入不了printString方法了。因为该方法被锁定了 object.printString(); } }; thread2.start(); } catch (InterruptedException e) { e.printStackTrace(); } } }
yield方法:
线程优先级:
守护线程: