Reputation: 3558
How can I tell Eclipse RCP Job management to run at most x jobs at the same time?
EDIT:
It works by using a custom scheduling rule as described in the answer.
Its important to never pass the same rule reference to more than one job.
Here is the class I use:
public class 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();
}
}
Upvotes: 2
Views: 883
Reputation: 329
Starting with Eclipse Mars (4.5), one can use job groups to limit the number of concurrent threads:
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);
Upvotes: 2
Reputation: 111198
The Job Manager does not have a way to limit the overall number of jobs.
For Jobs that you are creating you could create an ISchedulingRule
rule which limited the number of your jobs that run at the same time. Call Job.setRule(rule)
to set the rule on the job (do this before scheduling the job).
An example scheduling rule (from 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;
}
}
This stops more than one job that uses a particular object from running at a time.
Update:
The job manager checks the following conditions on a scheduling rule:
// 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));
Upvotes: 1