我有一个这样的线程池的场景,相信不少人都遇到过:
1,每一个用户均可以添加多个任务;
2,有不少的用户和不少的任务;
3,每一个用户添加的任务必须有序串行执行,即在同一时刻不能有同时执行一个用户的两个任务;
4,实时性:只要线程池线程有空闲的,那么用户提交任务后必须当即执行;尽量提升线程的利用率。
java
代码比较简洁,基本知足上述要求:优化
public class SerialThreadExecutor { private Executor executor; private ConcurrentMap<Object, SequentialJob> serialJobs = new ConcurrentHashMap<Object, SequentialJob>(); public SerialThreadExecutor(Executor executor) { super(); this.executor = executor; } public void executeSerially(Object key, Runnable r) { SequentialJob job = serialJobs.get(key); if (job == null) { job = new SequentialJob(key); SequentialJob oldJob = serialJobs.put(key, job); if (oldJob != null) { job = oldJob; } } job.addJob(r); } private class SequentialJob implements Runnable { private BlockingQueue<Runnable> jobs = new LinkedBlockingQueue<Runnable>(); private Object key; private AtomicBoolean running = new AtomicBoolean(false); public SequentialJob(Object key) { this.key = key; } public void run() { Runnable r = null; while (true) { try { r = jobs.poll(50, TimeUnit.MILLISECONDS); if (r != null) { r.run(); } else { synchronized (this) { if (jobs.isEmpty() && running.compareAndSet(true, false)) { return; } else { continue; } } } } catch (InterruptedException e) { // TODO e.printStackTrace(); } } } public void addJob(Runnable r) { synchronized (this) { jobs.add(r); if (running.compareAndSet(false, true)) { executor.execute(this); } } } } }
这个实现有几个缺陷:this
1,每次添加一个任务都要进入一次锁,有一点小小开销;spa
2,serialJobs会一直在内存中,当某个key的任务好久没有添加了,对应的SequentialJob对象一直存在,虽然不占用不少内存,但对于有洁癖的人来讲或,仍是不爽。线程
抛砖引玉,看看广大网友是否能够优化。code
(异常处理等细节你们就不要理会了)对象