具備相同屬性任務串行有序執行的線程池設計

我有一個這樣的線程池的場景,相信不少人都遇到過: 
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

(異常處理等細節你們就不要理會了)對象

相關文章
相關標籤/搜索