下面这段代码的线程会执行吗?
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时,就成了单线程运行了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)