優(yōu)化鎖,之前的鎖是采用一個(gè)static的Object實(shí)現(xiàn)的,這要就會(huì)有一個(gè)問題,如果我創(chuàng)建了多個(gè)Executer,那么所有Job都會(huì)持有一把鎖,既影響性能,也容易出現(xiàn)死鎖的情況。所以,改成每個(gè)Executer持有一把鎖。
Executer代碼如下:
- public class Executer {
- //計(jì)算已經(jīng)派發(fā)的任務(wù)數(shù)(條件謂詞)
- public static int THREAD_COUNT = 0;
- //存儲(chǔ)任務(wù)的執(zhí)行結(jié)果
- private List<Future<Object>> futres = new ArrayList<Future<Object>>();
- //條件隊(duì)列鎖
- public final Object lock = new Object();
- //線程池
- private ExecutorService pool = null;
- public Executer() {
- this(1);
- }
- public Executer(int threadPoolSize) {
- pool = Executors.newFixedThreadPool(threadPoolSize);
- }
- /**
- * 任務(wù)派發(fā)
- * @param job
- */
- public void fork(Job job){
- //設(shè)置同步鎖
- job.setLock(lock);
- //將任務(wù)派發(fā)給線程池去執(zhí)行
- futres.add(pool.submit(job));
- //增加線程數(shù)
- synchronized (lock) {
- THREAD_COUNT++;
- }
- }
- /**
- * 統(tǒng)計(jì)任務(wù)結(jié)果
- */
- public List<Object> join(){
- synchronized (lock) {
- while(THREAD_COUNT > 0){//檢查線程數(shù),如果為0,則表示所有任務(wù)處理完成
- System.out.println("threadCount: "+THREAD_COUNT);
- try {
- lock.wait();//如果任務(wù)沒有全部完成,則掛起。等待完成的任務(wù)給予通知
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- List<Object> list = new ArrayList<Object>();
- //取出每個(gè)任務(wù)的處理結(jié)果,匯總后返回
- for (Future<Object> future : futres) {
- try {
- Object result = future.get();//因?yàn)槿蝿?wù)都已經(jīng)完成,這里直接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();//執(zhí)行子類具體任務(wù)
- synchronized (lock) {
- //處理完業(yè)務(wù)后,任務(wù)結(jié)束,遞減線程數(shù),同時(shí)喚醒主線程
- Executer.THREAD_COUNT--;
- lock.notifyAll();
- }
- return result;
- }
- /**
- * 業(yè)務(wù)處理函數(shù)
- */
- public abstract Object execute();
-
- }
測(cè)試結(jié)果:
- 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!
這樣每個(gè)Executer就可以使用自己的lock,而相互不受同步的影響
posted on 2012-07-15 01:21
mixer-a 閱讀(1110)
評(píng)論(0) 編輯 收藏