栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java线程池为什么核心线程数为0依然能执行?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java线程池为什么核心线程数为0依然能执行?

下面这段代码的线程会执行吗?

ExecutorService es = 
new ThreadPoolExecutor(0, 100000, 100000, TimeUnit.HOURS,new linkedBlockingQueue<>());

答案是会。
但是为啥?

通过线程池的 execute 方法可以看到:

接着思考:
有没有进入队列?
先进入队列还是先创建线程?
都调用了队列的什么方法?

看最终代码:

public static void main(String[] args) {

         class MyQueue implements InvocationHandler {
             private BlockingQueue queue = null;
             public MyQueue(BlockingQueue queue){
                 this.queue = queue;
             }
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 System.out.println(method.getName() + "::::::::::::::::::::::::::" + Arrays.toString(args));
                 return method.invoke(queue,args);
             }
         }

        linkedBlockingQueue queue = new linkedBlockingQueue();
        BlockingQueue queue2 = (BlockingQueue)Proxy.newProxyInstance(Test.class.getClassLoader(),new Class[]{BlockingQueue.class},new MyQueue(queue));

        ExecutorService es = new ThreadPoolExecutor(1, 1, 100000, TimeUnit.HOURS, queue2, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                System.out.println("--------------------- new Thread ------------------------");
                return new Thread(r);
            }
        });
        es.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello : " + Thread.currentThread().getId());
                try {
                    Thread.sleep( 1 * 100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public String toString() {
                return "------------ test obj -------------";
            }
        });

        es.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello : " + Thread.currentThread().getId());
                try {
                    Thread.sleep( 1 * 100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public String toString() {
                return "------------ test obj -------------";
            }
        });
    }

变换ThreadPoolExecutor对象的第一个参数核心线程数:
核心线程数是0:
先走队列后走线程,执行的是队列的offer与poll

核心线程数大于0:
注意实际线程要大于核心线程数!
先走线程在走offer与take

核心线程数大于0:
注意实际线程要小于等于核心线程数!
先走线程,并且只走take

如果切换队列对象呢?

public static void main(String[] args) {

         class MyQueue implements InvocationHandler {
             private BlockingQueue queue = null;
             public MyQueue(BlockingQueue queue){
                 this.queue = queue;
             }
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 System.out.println(method.getName() + "::::::::::::::::::::::::::" + Arrays.toString(args) + "t" + Thread.currentThread().getId());
                 return method.invoke(queue,args);
             }
         }

        BlockingQueue queue = new SynchronousQueue();
        BlockingQueue queue2 = (BlockingQueue)Proxy.newProxyInstance(Test.class.getClassLoader(),new Class[]{BlockingQueue.class},new MyQueue(queue));

        ExecutorService es = new ThreadPoolExecutor(1, 5, 2, TimeUnit.HOURS, queue2, new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                System.out.println("--------------------- new Thread ------------------------");
                return new Thread(r);
            }
        });
        es.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello : " + Thread.currentThread().getId());
                try {
                    Thread.sleep( 1 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public String toString() {
                return "------------ test obj -------------";
            }
        });

        es.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello : " + Thread.currentThread().getId());
                try {
                    Thread.sleep( 1 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public String toString() {
                return "------------ test obj -------------";
            }
        });
        es.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello : " + Thread.currentThread().getId());
                try {
                    Thread.sleep( 1 * 100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public String toString() {
                return "------------ test obj -------------";
            }
        });
    }

再次尝试,注意观察线程ID

最终的出来的结论是:
1、当核心线程数为0的时候,会创建一个非核心线程进行执行
2、核心线程数不为0的时候,如果核心线程数在执行,会有一个非核心线程数从队列中取对象执行线程
3、核心线程数执行的是队列的take,非核心线程数执行队列的offer和poll
4、核心线程数不为0且队列为SynchronousQueue时,就成了单线程运行了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/693170.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号