• 终结任务


    线程状态

    新建状态

    线程被创建时,会短暂的处于这种状态。处于这种状态的线程已经分配了必须的系统资源,有资格获得cpu时间了,等待调度器把它转变为可运行状态或阻塞状态;

    就绪状态

    在这种状态下,只要调度器把时间片分配给线程,就可以马上运行;

    阻塞状态

    线程因为某个条件未满足,阻止了它的运行;这种状态会被调度器忽略,直到条件满足时,转为就绪状态;

    死亡状态

    线程运行结束或被中断后的状态;该状态不能被调度,不会分配cpu时间;

    线程进入阻塞状态的方式

    • 调用sleep方法
    • 调用wait方法
    • 任务等待某个输入输出完成
    • 调用其它同步控制方法,等待其它线程释放锁

    线程中断

    线程阻塞及中断

    先看一段代码,如下:

    package concurrency;
    
    import java.util.concurrent.*;
    import java.io.*;
    
    class SleepBlocked implements Runnable {
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("InterruptedException");
            }
            System.out.println("Exiting SleepBlocked.run()");
        }
    }
    
    class IOBlocked implements Runnable {
        private InputStream in;
    
        public IOBlocked(InputStream is) {
            in = is;
        }
    
        public void run() {
            try {
                System.out.println("Waiting for read():");
                in.read();
            } catch (IOException e) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("Interrupted from blocked I/O");
                } else {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("Exiting IOBlocked.run()");
        }
    }
    
    class SynchronizedBlocked implements Runnable {
        public synchronized void f() {
            while (true) // Never releases lock
                Thread.yield();
        }
    
        public SynchronizedBlocked() {
            new Thread() {
                public void run() {
                    f(); // Lock acquired by this thread
                }
            }.start();
        }
    
        public void run() {
            System.out.println("Trying to call f()");
            f();
            System.out.println("Exiting SynchronizedBlocked.run()");
        }
    }
    
    public class Interrupting {
        private static ExecutorService exec = Executors.newCachedThreadPool();
    
        static void test(Runnable r) throws InterruptedException {
            Future<?> f = exec.submit(r);
            TimeUnit.MILLISECONDS.sleep(100);
            System.out.println("Interrupting " + r.getClass().getName());
            f.cancel(true); // Interrupts if running
            System.out.println("Interrupt sent to " + r.getClass().getName());
        }
    
        public static void main(String[] args) throws Exception {
            test(new SleepBlocked());
            test(new IOBlocked(System.in));
            test(new SynchronizedBlocked());
            TimeUnit.SECONDS.sleep(3);
            System.out.println("Aborting with System.exit(0)");
            System.exit(0); // ... since last 2 interrupts failed
        }
    } 
    View Code

    以上代码中,展示了三种进入阻塞状态的情景:调用sleep方法,等待io,等待其它线程释放锁;

    以及尝试调用Future的cancel方法去中断阻塞的线程,从运行结果可以发现,只有sleep可以被中断,其它等待io和等待锁释放都不能被中断;这一点也可以从sleep方法会抛出InterruptedException异常看出来,其它两个不会抛出该异常;

    那么对于io阻塞和互斥锁阻塞的线程如何中断?

    中断io阻塞

    方式一,调用shutdownNow关闭线程池,调用close方法关闭IO流资源;

    方式二,使用nio

    中断互斥锁阻塞

    使用并发库中的ReentrantLock锁;

    ps:如果是同一个线程的话,是可以调用在同一个对象中的其它synchronized方法;

    检查中断

    调用Thread.interrupted(),查看interrupt()是否调用过,并清除中断状态,避免中断被通知两次;

  • 相关阅读:
    浅谈ASP.NET内部机制(四)
    用正则表达式看.NET编程正则核心对象详解(三 )
    【讨论】对技术的掌握到底应该又多深?
    掌握XML系列(三)创建格式良好的饿XML文档 续编
    浅谈ASP.NET的内部机制(一)
    浅谈ASP.NET内部机制(三)
    浅谈ASP.NET的内部机制(二)
    小工具大智慧
    老生常谈:抽象工厂模式
    又说:程序员的成长过程
  • 原文地址:https://www.cnblogs.com/chenpi/p/5325364.html
Copyright © 2020-2023  润新知