前言:
关于这个延时线程池,我相信大部分人还是理解的不够深。包括我自己。大部分任务,如果开一个延时线程池,里面有四个线程。那么并发过来,会不会没有线程可用,因为之前的线程都在延时中。这种理解是错误的。我们用代码来证明。
正文:
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); } } }
从上面的测试结果看出一个结论:延时和线程没关,延时其实是放在线程池底层构造的一个延时队列中的,这个队列放的是延时任务。线程池,只负责从对列中取出任务来执行。延时也不会占用线程
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于