zoukankan      html  css  js  c++  java
  • ThreadPoolExecutor介绍

    ThreadPoolExecutor的说明

    ThreadPoolExecutor常见的操作主要有以下几个方法:

    1. getPoolSize():返回线程池实际的线程数。
    2. getActiveCount():返回在执行者中正在执行任务的线程数。
    3. getCompletedTaskCount():返回执行者完成的任务数。
    4. submit(): 提交一个线程给线程执行者,如果执行者有空余线程,则直接执行;否则等待直到有空闲线程。这里调用sumbit后,并不会阻塞调用线程。调用者所在的线程和执行的线程并发运行。

    下面要着重介绍两个方法:

    1. shutdown(): 调用这个方法后,线程执行者在完成当前已经提交的所有任务后,结束运行。
      a. 在主线程中如果调用线程执行者的这个方法,并不会使线程执行者中已经submit的任务中断(无论是待执行、执行中)
      b. 调用shutdown会通知执行者,后面提交的任务“不允许接受”,在shutdown后提交任务,会抛出RejectedExecutionException的异常信息。
    2. shutdownNow(): 调用这个方法后,立即停止执行者的运行。返回待执行的Task。
      a. 中断所有正在执行的线程: 正在执行的线程会收到中断信息。抛出InterruptedException
      b. 后面提交的任务“不允许接受”,在shutdownNow后再调用submit提交任务,会抛出RejectedExecutionException的异常信息。

    code1:

    public class ThreadPoolTest {
        public static void main(String[] args) {
            ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
            for (int i = 0; i < 3; i++) {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(100);
                            System.out.println("sub thread classs");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            executor.shutdown();
            System.out.println("Main classs");
        }
    }

    结果:

    Main classs
    sub thread classs
    sub thread classs
    sub thread classs

    说明:
    调用executor.submit后,并不会阻塞主线程。主线程和提交到执行者中的线程并发执行。

    code2:

    public class ThreadPoolTest {
        public static void main(String[] args) {
            ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
            for (int i = 0; i < 3; i++) {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(100);
                            System.out.println("sub thread classs");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            executor.shutdown();
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        System.out.println("sub thread classs");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            System.out.println("Main classs");
        }
    }

    结果:

    Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task 
    java.util.concurrent.FutureTask@1c910477 rejected from java.util.concurrent.
    ThreadPoolExecutor@74bc2f47[Shutting down, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
    at ThreadPoolTest.ThreadPoolTest.main(ThreadPoolTest.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
    sub thread classs
    sub thread classs
    sub thread classs

    说明:
    调用executor.shutdown()后,如果再调用submit()方法,调用线程会抛出rejectedExecution,如果没有try,cacth直接中断
    后续的操作。

    code3:

    public class ThreadPoolTest {
        public static void main(String[] args) {
            ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
            for (int i = 0; i < 3; i++) {
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(100);
                            System.out.println("sub thread classs");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            List<Runnable> list=executor.shutdownNow();
            System.out.println("list size:"+list.size());
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        System.out.println("sub thread classs");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            System.out.println("Main classs");
        }
    }

    结果:

    list size:0
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at ThreadPoolTest.ThreadPoolTest$1.run(ThreadPoolTest.java:16)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at ThreadPoolTest.ThreadPoolTest$1.run(ThreadPoolTest.java:16)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at ThreadPoolTest.ThreadPoolTest$1.run(ThreadPoolTest.java:16)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
    Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task 
    java.util.concurrent.FutureTask@3a9d04dc rejected from java.util.concurrent.ThreadPoolExecutor@1aaa2594
    [Shutting down, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 1]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
    at ThreadPoolTest.ThreadPoolTest.main(ThreadPoolTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

    说明:
    调用shutDownNow()后,直接中断所有的线程。并且后面submit()task会抛出rejectedExecution。

  • 相关阅读:
    Spring配置通过动态工厂方法创建的bean
    Spring配置通过静态工厂方法创建的bean
    SpringMVC针对post请求乱码的处理
    SpringMVC的HelloWorld快速入门!
    SpringMVC和Spring的关系
    pageContext、request、session和application区别
    orcale 实现 sql server 里面的表值函数SPLIT
    查询语句有 or 会导致查询速度变慢问题解决
    用谷歌浏览器以及插件 测试接口
    OraCle 记录 实现 sql中的 for xml path ('')
  • 原文地址:https://www.cnblogs.com/limingluzhu/p/4326009.html
Copyright © 2011-2022 走看看