Eclipse RCP作业:限制并发执行作业的数量

时间:2014-04-11 08:37:30

标签: java eclipse-rcp

如何告诉Eclipse RCP作业管理同时运行最多x个作业?

编辑:

它的工作原理是使用答案中描述的自定义调度规则。

重要的是永远不要将相同的规则引用传递给多个作业。

这是我使用的课程:

公共课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();
}

}

2 个答案:

答案 0 :(得分:1)

作业管理器无法限制作业的总数。

对于您正在创建的作业,您可以创建ISchedulingRule规则,该规则限制同时运行的作业数量。调用Job.setRule(rule)在作业上设置规则(在安排作业之前执行此操作)。

示例调度规则(来自Java Debug):

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));

答案 1 :(得分:1)

从Eclipse Mars(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);