優化鎖,之前的鎖是采用一個static的Object實現的,這要就會有一個問題,如果我創建了多個Executer,那么所有Job都會持有一把鎖,既影響性能,也容易出現死鎖的情況。所以,改成每個Executer持有一把鎖。
Executer代碼如下:
- public class Executer {
- //計算已經派發的任務數(條件謂詞)
- public static int THREAD_COUNT = 0;
- //存儲任務的執行結果
- private List<Future<Object>> futres = new ArrayList<Future<Object>>();
- //條件隊列鎖
- public final Object lock = new Object();
- //線程池
- private ExecutorService pool = null;
- public Executer() {
- this(1);
- }
- public Executer(int threadPoolSize) {
- pool = Executors.newFixedThreadPool(threadPoolSize);
- }
- /**
- * 任務派發
- * @param job
- */
- public void fork(Job job){
- //設置同步鎖
- job.setLock(lock);
- //將任務派發給線程池去執行
- futres.add(pool.submit(job));
- //增加線程數
- synchronized (lock) {
- THREAD_COUNT++;
- }
- }
- /**
- * 統計任務結果
- */
- public List<Object> join(){
- synchronized (lock) {
- while(THREAD_COUNT > 0){//檢查線程數,如果為0,則表示所有任務處理完成
- System.out.println("threadCount: "+THREAD_COUNT);
- try {
- lock.wait();//如果任務沒有全部完成,則掛起。等待完成的任務給予通知
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- List<Object> list = new ArrayList<Object>();
- //取出每個任務的處理結果,匯總后返回
- for (Future<Object> future : futres) {
- try {
- Object result = future.get();//因為任務都已經完成,這里直接get
- list.add(result);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return list;
- }
- }
Job類:
- public abstract class Job implements Callable<Object> {
-
- //鎖
- private Object lock = null;
-
- void setLock(Object lock) {
- this.lock = lock;
- }
-
- @Override
- public Object call() throws Exception {
- Object result = this.execute();//執行子類具體任務
- synchronized (lock) {
- //處理完業務后,任務結束,遞減線程數,同時喚醒主線程
- Executer.THREAD_COUNT--;
- lock.notifyAll();
- }
- return result;
- }
- /**
- * 業務處理函數
- */
- public abstract Object execute();
-
- }
測試結果:
- threadCount: 10
- running thread id = 8
- running thread id = 10
- running thread id = 9
- running thread id = 12
- running thread id = 11
- threadCount: 8
- threadCount: 7
- threadCount: 6
- threadCount: 5
- running thread id = 12
- running thread id = 8
- running thread id = 11
- threadCount: 2
- running thread id = 10
- threadCount: 1
- running thread id = 9
- ResultSize: 10
- time: 2001
OK!
這樣每個Executer就可以使用自己的lock,而相互不受同步的影響
posted on 2012-07-15 01:21
mixer-a 閱讀(1110)
評論(0) 編輯 收藏