2014-04-11 75 views
2

如何告知Eclipse RCP作業管理最多同時運行x個作業?Eclipse RCP IJob:限制併發執行作業的數量

編輯:

它的工作原理是利用在回答中描述的自定義調度規則。

重要的是永遠不要將相同的規則引用傳遞給多個作業。

這裏是我使用的類:

公共類JobMaster {

private class Listener implements IJobChangeListener { 

    @Override 
    public void aboutToRun(final IJobChangeEvent event) { 
    } 

    @Override 
    public void awake(final IJobChangeEvent event) { 
    } 

    @Override 
    public void done(final IJobChangeEvent event) { 
     synchronized (JobMaster.this) { 
      running--; 
      System.err.println("now running " + running); 
     } 
    } 

    @Override 
    public void running(final IJobChangeEvent event) { 
     synchronized (JobMaster.this) { 
      running++; 
      System.err.println("now running " + running); 
     } 
    } 

    @Override 
    public void scheduled(final IJobChangeEvent event) { 

    } 

    @Override 
    public void sleeping(final IJobChangeEvent event) { 
    } 

} 

private class MyRule implements ISchedulingRule { 

    public MyRule() { 

    } 

    @Override 
    public boolean contains(final ISchedulingRule rule) { 
     if (rule == this) { 
      return true; 
     } 
     return false; 

    } 

    @Override 
    public boolean isConflicting(final ISchedulingRule rule) { 
     synchronized (JobMaster.this) { 
      if (rule == this) { 
       return true; 
      } 
      if (rule instanceof MyRule) { 
       return running >= maxRun; 
      } 
      return false; 
     } 
    } 
} 

private final Listener l = new Listener(); 

private final int maxRun; 

private volatile int running = 0; 

public JobMaster(final int maxRun) { 
    this.maxRun = maxRun; 

} 

public synchronized void add(final Job j) { 
    j.setRule(new MyRule()); 
    j.addJobChangeListener(l); 
    j.schedule(); 
} 

}

回答

1

作業管理器沒有辦法限制的職位總數。

對於您正在創建的作業,您可以創建一個ISchedulingRule規則,該規則限制同時運行的作業數量。致電Job.setRule(rule)在作業上設置規則(在安排作業之前執行此操作)。

一個例子的調度規則(從Java調試):

class SerialPerObjectRule implements ISchedulingRule { 

    private Object fObject = null; 

    public SerialPerObjectRule(Object lock) { 
    fObject = lock; 
    } 

    public boolean contains(ISchedulingRule rule) { 
    return rule == this; 
    } 

    public boolean isConflicting(ISchedulingRule rule) { 

    if (rule instanceof SerialPerObjectRule) { 
     SerialPerObjectRule vup = (SerialPerObjectRule)rule; 
     return fObject == vup.fObject; 
    } 

    return false; 
    } 
} 

這將停止使用特定對象從同時運行多個作業。

更新:

作業管理器檢查在調度規則如下條件:

// contains method must be reflexive 
Assert.isLegal(rule.contains(rule)); 

// contains method must return false when given an unknown rule 
Assert.isLegal(!rule.contains(nullRule)); 

// isConflicting method must be reflexive 
Assert.isLegal(rule.isConflicting(rule)); 

// isConflicting method must return false when given an unknown rule 
Assert.isLegal(!rule.isConflicting(nullRule)); 
+0

我已經嘗試過使用SchedulingRule。不幸的是,這是行不通的: java.lang.IllegalArgumentException: \t at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63) \t at org.eclipse.core.runtime.Assert.isLegal(Assert .java:47) \t at org.eclipse.core.internal.jobs.JobManager.validateRule(JobManager.java:1573) Assert.isLegal(rule.isConflicting(rule)); – kerner1000

+0

這是告訴你,你的規則的邏輯是不正確的。該規則必須是'反身' - 帶有相同規則的'isConflicting',因爲該參數必須返回true。添加了要求的答案 –

0

與Eclipse火星(4.5),可以使用工作組來限制併發線程數開始:

JobGroup jobGroup = new JobGroup("Job...", /* maxThreads*/ 10, /* seedJobsCount */ 100); 

for (int ii = 0; ii < 100; ii++) 
{    
    Job job = new Job("job name") 
    { 
     @Override 
     protected IStatus run(IProgressMonitor monitor) 
     { 
      // do something 
      return Status.OK_STATUS; 
     } 
    }; 
    job.setJobGroup(jobGroup); 
    job.schedule(); 
} 

jobGroup.join(10000, monitor); 
+0

這太好了,我會試試看,謝謝! – kerner1000