多线程--中断线程

一 . 在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

posted @ 2017-07-17 15:23  cello_ist  阅读(226)  评论(0编辑  收藏  举报