多线程--中断线程
一 . 在java中有以下三种方法可以停止正在运行的线程:
1 . 使用退出标志使线程正常退出,也就是当run方法完成后线程终止
2 . 使用stop() 方法强行终止线程,但是不推荐这么做,因为stop()方法和suspend()及resume()方法一样是不安全的,使用它们可能产生不可预料的结果
3 . 使用interrupt()方法终止线程(注意:interrupt方法并不会马上停止当前线程,它仅仅是在当前线程中打了一个停止的标记)
二 . 关于interrupt(),isInterrupted(),interrupted()方法
1 . interrupt()方法:
// Interrupts this thread public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (blockerLock) { Interruptible b = blocker; if (b != null) { interrupt0(); // Just to set the interrupt flag b.interrupt(this); return; } } interrupt0(); }
2 . isInterrupted()方法:
/** * Tests whether the current thread has been interrupted. * The interrupted status of the thread is unaffected by this method. * 测试当前线程是否已经被标记为中断状态,此方法不会改变当前线程的状态 */ public boolean isInterrupted() { return isInterrupted(false);//调用本地方法isInterrupted(boolean ClearInterrupted) } private native boolean isInterrupted(boolean ClearInterrupted);
3 . interrupted()方法:
/** * Tests whether the current thread has been interrupted. * The interrupted status of the thread is is cleared by this method。In * other words, if this method were to be called twice in succession, the * second call would return false * 测试当前线程是否已经被标记为中断状态,此方法会清除当前线程的 * 中断状态,换句话说,如果这个方法被调用两次,第二次调用将会返回false */ public static boolean interrupted() { return currentThread().isInterrupted(true);// 调用本地方法isInterrupted(boolean ClearInterrupted) } private native boolean isInterrupted(boolean ClearInterrupted);
下面的示例代码为中断主线程
public class MyThread extends Thread { public MyThread(String threadName) { super(threadName); } /** * 主线程 * @Description * @author niepei * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { System.out.println("【 " + Thread.currentThread().getName() + "】 has begin "); MyThread thread = new MyThread("test"); thread.start(); Thread.sleep(1000); Thread.currentThread().interrupt(); // 将主线程标记为中断 System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.currentThread().isInterrupted());//true System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.currentThread().isInterrupted());//true System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.interrupted());//true System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.interrupted());//false System.out.println("【 " + Thread.currentThread().getName() + "】 has end"); } /** * 重写run方法 * @see java.lang.Thread#run() */ @Override public void run() { System.out.println("【 " + Thread.currentThread().getName() + "】 has begin "); for(int i=1;i<=10000;i++){ System.out.println("i = " + i); } System.out.println("==============> " + Thread.currentThread().getName() + " has end "); } }
下面的示例代码为在主线程中中断其他线程:
public class MyThread extends Thread { public MyThread(String threadName) { super(threadName); } /** * 主线程 * @Description * @author niepei * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { System.out.println("--------------> " + Thread.currentThread().getName() + " has begin "); MyThread thread = new MyThread("test"); thread.start(); Thread.sleep(1000); thread.interrupt(); System.out.println(thread.getName()+" interrupted : " + thread.isInterrupted());//true System.out.println("--------------> " + Thread.currentThread().getName() + " has end "); } /** * 重写run方法 * @see java.lang.Thread#run() */ @Override public void run() { System.out.println("==============> " + Thread.currentThread().getName() + " has begin "); for(int i=1;i<=500000;i++){ System.out.println("i = " + i); } System.out.println("==============> " + Thread.currentThread().getName() + " has end "); } }
三 . interrupt()方法 和 sleep()方法
当线程休眠时被中断:在sleep状态下中断某一线程,会进入随后的catch语句并 清除状态值 ,使之变成false
public class MyThread extends Thread { public MyThread(String threadName) { super(threadName); } /** * 主线程 * @Description * @author niepei * @param args * @throws InterruptedException */ public static void main(String[] args) { System.out.println("【 " + Thread.currentThread().getName() + "】 has begin "); MyThread thread = new MyThread("test"); thread.start(); thread.interrupt(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("【 " + Thread.currentThread().getName() + "】 has end "); } /** * 重写run方法 * @see java.lang.Thread#run() */ @Override public void run() { System.out.println("【 " + Thread.currentThread().getName() + "】 has begin "); try { System.out.println("--> run has begin"); Thread.sleep(200000); System.out.println("--> run has end"); } catch (InterruptedException e) { System.out.println("--> interrupt in sleep , interrupted : " + this.isInterrupted()); } System.out.println("【 " + Thread.currentThread().getName() + "】 has end "); } } 运行结果如下: 【 main】 has begin 【 test】 has begin --> run has begin --> interrupt in sleep , interrupted : false 【 test】 has end 【 main】 has end
四 . suspend() 方法和 resume()方法
suspend()方法用于暂停当前线程,而resume()方法用于恢复线程的执行,但是这两个方法如果使用不当很容易造成公共同步对象的独占,使其他线程无法访问公共同步对象。
public class Test { public synchronized void printString() { System.out.println("【 " + Thread.currentThread().getName() + "】 has begin "); if (Thread.currentThread().getName().equals("A")) { System.out.println("【 " + Thread.currentThread().getName() + "】 has been suspend"); Thread.currentThread().suspend(); } System.out.println("【 " + Thread.currentThread().getName() + "】 has end "); } public static void main(String[] args) throws InterruptedException { System.out.println("【 " + Thread.currentThread().getName() + "】 has begin "); final Test test = new Test(); Thread thread1 = new Thread() { @Override public void run() { test.printString(); } }; thread1.setName("A"); thread1.start(); Thread.sleep(1000); Thread thread2 = new Thread() { @Override public void run() { System.out.println("【 " + Thread.currentThread().getName() + "】 can't start,because printString() is locked by Thread 【A】 and suspend forever "); test.printString(); } }; thread2.setName("B"); thread2.start(); System.out.println("【 " + Thread.currentThread().getName() + "】 has end "); } } 运行结果如下: 【 main 】 has begin 【 A 】 has begin 【 A 】 has been suspend 【 main 】 has end 【 B 】 can't start,because printString() is locked by Thread 【A】 and suspend forever
五 . yield方法:yield()用于放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间,但放弃的时间不确定有可能刚刚放弃又重新获取CPU时间片
六.线程的优先级:可以调用setPriority()方法设置线程的优先级,最高10,最低1,线程的优先级具有继承性,假设A线程启动了B线程,则B线程具有与A一样的优先级,高优先级的线程总是大部分先执行完,但不代表高优先级的线程总是全部先执行完
七.守护线程:java中有两种线程,一种用户线程一种守护线程,守护线程是一种特殊的线程,当进程中不存在非守护线程了则守护线程会自动销毁,典型的守护线程就是GC线程,当JVM实例中最后一个非守护线程执行结束之后,它才会和JVM一起结束工作。可以调用setDaemon(true)将当前线程设置为守护线程。
参考博客:http://www.mamicode.com/info-detail-517008.html