Java 多线程 :入门- 简单试验ExecuteorService
Posted ajjiangxin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 多线程 :入门- 简单试验ExecuteorService相关的知识,希望对你有一定的参考价值。
首先,根据其他文章提到的,我也实验了的Runnable跟Callable的差别:
1)Callable接口的call()方法有返回值,这样方便处理“需要将一个对象加工并返回”的需求(Runnable的run()没有返回值,但可以通过回调的方式在run()内部解决);
2)都使用ExecutorService来submit()时,均返回Future<T>,但前者的future.get()为空,后者可以有内容;
试验一下Executors.newFixedThreadPool(), 代码如下:
public class testExecutorShutdown{ public static void main(String[] args) throws InterruptedException, ExecutionException{ ExecutorService executor = Executors.newFixedThreadPool(10); executor.submit(new CallableA(executor)); } } class CallableA implements Callable<Object> { class newRunnable implements Runnable{ private int id; public newRunnable(int id){ this.id = id; } @Override public void run() { System.out.println("newRunnable:"+id+" executed; Thread hashCode: "+Thread.currentThread().hashCode()); } } ExecutorService executor = null; public CallableA(ExecutorService executor){ this.executor = executor; } @Override public Object call() { for(int i=0; i<100; i++){ executor.submit(new newRunnable(i)); } return null; } }
结果:
newRunnable:9 executed; Thread hashCode: 777173972
newRunnable:10 executed; Thread hashCode: 777173972
newRunnable:3 executed; Thread hashCode: 622087230
newRunnable:12 executed; Thread hashCode: 622087230
newRunnable:7 executed; Thread hashCode: 348776228
newRunnable:13 executed; Thread hashCode: 622087230
newRunnable:14 executed; Thread hashCode: 622087230
newRunnable:6 executed; Thread hashCode: 948531615
newRunnable:17 executed; Thread hashCode: 948531615
newRunnable:18 executed; Thread hashCode: 948531615
newRunnable:19 executed; Thread hashCode: 948531615
newRunnable:20 executed; Thread hashCode: 948531615 ......
这里只贴了结果的一部分,可以看到newFixedThreadPool会把一个Runnable或Callable任务拆分给最多n个(new的时候定义的)线程来做,且各做一部分,不会重复,但顺序不一定。
另外,我尝试了在run()方法中,插入if(i==50){executor.shutdownNow(); System.out.pringln(...); //或shutdown()}, 结果还是有其他的线程的内容打印出来,这里说明了两个问题:
1)任务的拆分是submit()方法(或execute()方法)一开始调用时就做好的,然后没有特定顺序地同时开始,这印证了上一部分的结论,更是由于此,shutdown()和shutdownNow()的执行点if(i==50)其实是没有意义的,因为什么时候i==50的那个newRunnable线程是不一定的,且就算执行了,System.out.println()方法打印出结果的时刻并不准确代表了所有线程的执行进度,可能shutdownNow()之前很多线程已经开启,只是打印到控制台比较晚,才出现了上述结果;
2)另外,文档给出shutdownNow()方法的解释是“对于已经开始执行的线程,不一定能彻底shutdown”,原文如下,说明这种方法来完全shutdown线程池中的线程是不靠谱的:
shutdownNow List<Runnable> shutdownNow() Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that. There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
写的很差哈,一步步简单理解Executor线程池的作用,未完待续。。。
以上是关于Java 多线程 :入门- 简单试验ExecuteorService的主要内容,如果未能解决你的问题,请参考以下文章