package com.demo.service.include.impl;
import java.util.concurrent.CountDownLatch;
public class A implements Runnable{
CountDownLatch latch;//同步辅助类
private String flag;
public CountDownLatch getLatch() {
return latch;
}
public void setLatch(CountDownLatch latch) {
this.latch = latch;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
@Override
public void run() {
try{
setFlag("B");
throw new Exception();
}catch(Exception e){
setFlag("A");
}finally{
latch.countDown();
}
}
}
package com.demo.service.include.impl;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class B {
public static void main(String[] args) throws InterruptedException {
ExecutorService t=Executors.newCachedThreadPool();
CountDownLatch latch=new CountDownLatch(1);
A a=new A();
a.setLatch(latch);
t.execute(a);
latch.await();
System.out.println(a.getFlag());
}
}
以上代码在运行完后,没有立即退出,不知道为什么卡住,最终也打印出A结果
假设在通过spring的方式将a进行配置,返回值却获取不到,这个是为什么?
------解决方案--------------------
虚拟机实例停止运行的条件是:只有守护线程时才退出;
显然,即使main线程退出,若线程池还有非守护线程,自然JVM还在运行了;
------解决方案--------------------
线程池,简而言之,就是线程的池,在池中容纳一定数量的线程,有任务要执行时,从池中取出一个线程,执行所需的任务,执行完成后,线程并不是直接结束,而是等待下一个任务的到来,这样可以避免每次有任务需要执行时都要重复创建线程的开销。当然线程池中的线程并不是永不结束,可以设置超时时间,如果一个空闲的线程等待了超过超时时间还没有任务需要执行,那么线程就自动结束,也就达到了从线程池中删除线程的目的。
具体可以看下ThreadPoolExecutor中的:
Runnable getTask() {
for (;;) {
try {
int state = runState;
if (state > SHUTDOWN)
return null;
Runnable r;
if (state == SHUTDOWN) // Help drain queue
r = workQueue.poll();
else if (poolSize > corePoolSize
------解决方案--------------------
allowCoreThreadTimeOut)
r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
else
r = workQueue.take();
if (r != null)
return r;
if (workerCanExit()) {
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers();
return null;
}
// Else retry
} catch (InterruptedException ie) {
// On interruption, re-check runState
}
}
}