多线程awaitTermination和shutdown的使⽤问题
最近做⼀个抓取⽹页数据的任务,由于需要抓取的数据量⽐较⼤,并且抓取的间隔⽐较短,每次抓取任务启动后会有多次⽹络请求,为了提⾼抓取的效率采⽤了多线程的⽅式实现
ExecutorService pool = new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE, KEEPALIVETIME, TimeUnit.MILLISECONDS,new LinkedBlockin for (BaInfoPO baInfoPO : baInfos) {
暧昧的英文UThread uThread = new UThread(baInfoPO
);
validation
初始时采⽤了上图的实现⽅式,其中CORE_POOL_SIZE为10,max_pool_size为16,采⽤此⽅法启动后发现程序⼀直处于运⾏状态,⽆法结束,通过jdk⾃带
wifi怎么读的⼯具JVM查看程序的执⾏状态后发现,此时所有线程都处于await状态
开始时认为既然所有的线程都处于等待状态,⼀定是资源同步出现了问题,导致所有线程都在等待某个共享资源锁的释放,于是重新检查了⼀下对临界资
宁波培训学校源的处理是否存在问题,发现并没有什么问题。
这就怪了,既然并没有任何资源占⽤⽽没有释放,为什么程序仍不能正常结束呢?
Google了⼀下这种情况产⽣的各种可能原因,仍不能解决遇到的问题,⽆奈之下看了⼀眼⽇志,看完后就更奇怪了,⽇志中显⽰每个线程的任务都正确的执⾏
结束了,正常情况下java虚拟机应该停⽌了,这样的话应该不是⼦线程中出现了问题,⽽是主线程出
现了问题,JVM中显⽰的10个线程不是出现了问题,⽽是线程池中的线程,因为 CORE_POOL_SIZE为10所以会有是10个线程处于等待状态,等待分配任务。
接下来开始检查主线程中代码(即上图):
其实上⾯的代码本⾝并没有任何问题,我们先来看⼀下java官⽅⽂档对pool.awaitTermination⽅法的注释:
/**
* Blocks until all tasks have completed execution after a shutdown
* request, or the timeout occurs, or the current thread is
aeo是什么意思>八年级上册英语课文翻译* interrupted, whichever happens first.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
editions
bed* @return <tt>true</tt> if this executor terminated and
* <tt>fal</tt> if the timeout elapd before termination
* @throws InterruptedException if interrupted while waiting
bachelordegree>幼兽*/
⼤概意思是这样的:该⽅法调⽤会被阻塞,直到所有任务执⾏完毕并且shutdown请求被调⽤,或者参数中定义的timeout时间到达或者当前线程被打断,这⼏种情况任意⼀个发⽣了就会导致该⽅法的执⾏。
这样就明⽩了:
当我们调⽤pool.awaitTermination时,⾸先该⽅法会被阻塞,这时会执⾏⼦线程中的任务,⼦线程执⾏完毕后该⽅法仍然会被阻塞,因为shutdown()⽅法还
未被调⽤,⽽代码中将shutdown的请求放在了awaitTermination之后,这样就导致了只有awaitTermination⽅法执⾏完毕后才会执⾏shutdown请求,这样就造
成了死锁。
解决办法⾃然就很简单了,调换下位置就可以了。