前言:
关于这个延时线程池,我相信大部分人还是理解的不够深。包括我自己。大部分任务,如果开一个延时线程池,里面有四个线程。那么并发过来,会不会没有线程可用,因为之前的线程都在延时中。这种理解是错误的。我们用代码来证明。
正文:
WorldManager
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class WorldManager {
private static final WorldManager worldManager = new WorldManager();
public static WorldManager getInstance() {
return worldManager;
}
private ScheduledExecutorService aiSheduled = Executors.newScheduledThreadPool(4, new ThreadFactory() {
AtomicInteger index = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "AI_TASK_"
+ index.incrementAndGet());
}
});
public ScheduledFuture<?> scheduledAi(Runnable task, long delay, TimeUnit unit) {
return aiSheduled.schedule(task, delay, unit);
}
}
TestSchedule
import java.util.Random;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestSchedule {
private static final Logger LOG = LoggerFactory.getLogger(TestSchedule.class);
private ScheduledFuture<?> aiShedule;
public ScheduledFuture<?> getAiShedule() {
return aiShedule;
}
private class TestEvent implements Runnable{
private Integer pid;
public TestEvent(Integer _pid){
this.pid = _pid;
}
@Override
public void run() {
try {
LOG.info("------------------------------------------------"+pid);
Random random = new Random(System.currentTimeMillis());
int delay = random.nextInt(20) + 1;
aiShedule = WorldManager.getInstance().scheduledAi(new TestEvent(pid), delay, TimeUnit.SECONDS);
//LOG.info(aiShedule.hashCode()+"");
} catch (NumberFormatException e) {
LOG.error(e.getMessage(), e);
}
}
}
public void ready(Integer i){
LOG.info("======================================="+i);
//worldManager.getInstance是一个线程池,里面总共有四个线程
aiShedule = WorldManager.getInstance().scheduledAi(new TestEvent(i), 5, TimeUnit.SECONDS);
//LOG.info(aiShedule.hashCode()+"");
}
public static void main(String[] args) {
for(int i =1 ;i <=100;i++){
new TestSchedule().ready(i);
}
}
}
从上面的测试结果看出一个结论:延时和线程没关,延时其实是放在线程池底层构造的一个延时队列中的,这个队列放的是延时任务。线程池,只负责从对列中取出任务来执行。延时也不会占用线程
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于