具有相同属性任务串行有序执行的线程池设计_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 具有相同属性任务串行有序执行的线程池设计

具有相同属性任务串行有序执行的线程池设计

 2014/9/4 18:26:35  OpenMind  程序员俱乐部  我要评论(0)
  • 摘要:我有一个这样的线程池的场景,相信很多人都遇到过:1,每个用户都可以添加多个任务;2,有很多的用户和很多的任务;3,每个用户添加的任务必须有序串行执行,即在同一时刻不能有同时执行一个用户的两个任务;4,实时性:只要线程池线程有空闲的,那么用户提交任务后必须立即执行;尽可能提高线程的利用率。代码比较简洁,基本满足上述要求:publicclassSerialThreadExecutor{privateExecutorexecutor;privateConcurrentMap<Object
  • 标签:执行 设计 线程

我有一个这样的线程池的场景,相信很多人都遇到过:?
1,每个用户都可以添加多个任务;?
2,有很多的用户和很多的任务;?
3,每个用户添加的任务必须有序串行执行,即在同一时刻不能有同时执行一个用户的两个任务;?
4,实时性:只要线程池线程有空闲的,那么用户提交任务后必须立即执行;尽可能提高线程的利用率。?

代码比较简洁,基本满足上述要求:

class="java" name="code">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);
				}
			}
		}
	}
}

这个实现有几个缺陷:

1,每次添加一个任务都要进入一次锁,有一点小小开销;

2,monospace; font-size: 1em; line-height: 1.5; background-color: #fafafa;">serialJobs会一直在内存中,当某个key的任务很久没有添加了,对应的SequentialJob对象一直存在,虽然不占用很多内存,但对于有洁癖的人来说或,还是不爽。

?

抛砖引玉,看看广大网友是否可以优化。

异常处理等细节大家就不要理会了)

?

发表评论
用户名: 匿名