• 多线程--中断线程


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

  • 相关阅读:
    Delphi DataSnap入门操作,动起来
    Delphi 记录Record和字符串String相互赋值
    转载:JAVA每天学习
    转载:IntelliJ IDEA 的使用方法总结
    合并多个txt
    如何用vosviewer进行时间线分析——结合pajek
    链路预测(一)
    【js】百分比保留两位小数
    【基础】float保留两位小数
    【js】鼠标悬停显示信息
  • 原文地址:https://www.cnblogs.com/pepper7/p/7194958.html
Copyright © 2020-2023  润新知