1. 一般的长时间的后台工作都应该使用Job,Job可分为三个等级:
System级:对用户没有反馈
Default级:在状态栏中有反馈
User级: 有一个进度条对话框,可取消和后台运行
一般使用如下:
Job job = new Job("Long Running Job") {
protected IStatus run(IProgressMonitor monitor) {
try {
while (hasMoreWork) {
// do some work
// ...
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
}
} finally {
schedule(60000);
// start again in an hour
}
return Status.OK_STATUS;
}
};
job.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
if (event.getResult().isOK()) {
// postMessage("Job completed successfully");
} else { // postError("Job did not complete successfully");
}
}
});
job.setSystem(true);
job.schedule(); // start as soom as possible
2. 如果有多个Job要运行,并且想统一管理的话,可以使用Job族。一个Job族可以对一组Job进行统一的操作
管理,如:cancel, find, join, sleep, 和 wakeUp等等。一般使用如下:
1. 定义一个Job族类:
class FamilyMember extends Job {
private String lastName;
public FamilyMember(String firstName, String lastName) {
super(firstName + " " + lastName);
this.lastName = lastName;
}
protected IStatus run(IProgressMonitor monitor) {
// Take care of family business
return Status.OK_STATUS;
}
public boolean belongsTo(Object family) {
return lastName.equals(family);
}
}
2. 管理一组族内的Job:
//Create some family members and schedule them
new FamilyMember("Bridget", "Jones").schedule();
new FamilyMember("Tom", "Jones").schedule();
new FamilyMember("Indiana", "Jones").schedule();
// Obtain the Platform job manager
IJobManager manager = Platform.getJobManager();
// put the family to sleep
manager.sleep("Jones");
// put the family to sleep for good!
manager.cancel("Jones"); //canceled
3. 为了避免死锁,需要对多个job之间资源访问进行管理和控制,这是通过定义调度规则来实现的(Scheduling rules)。每个调度规则都是ISchedulingRule的实现,通常使用如下:
ISchedulingRule myRule = ... ;
job.setSchedulingRule(myRule);
ISchedulingRule接口中定义了两个方法,如下:
public interface ISchedulingRule {
//用来判断是否冲突
public boolean isConflicting(ISchedulingRule rule);
//用来判断所需要条件的满足
public boolean contains(ISchedulingRule rule);
}
Eclipse中所有资源类都实现了接口ISchedulingRule,所以本身就是一个规则类。通常使用如下:
1. job.setRule(null):此时所操作的资源的锁会一个一个的去取得
2. 使用MultiRule通常来说我们都应该使用第二种方式,因为第一种方式是可打断的!
下面就介绍多个规则的使用。一般使用多个规则都是通常以下方式实现的:
public ISchedulingRule createRule(IFile[] files) {
ISchedulingRule combinedRule = null;
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace()
.getRuleFactory();
for (int i = 0; i < files.length; i++) {
ISchedulingRule rule = ruleFactory.createRule(files[i]);
combinedRule = MultiRule.combine(rule, combinedRule);
}
return combinedRule;
}
这就是,我们把所要访问到的锁都合并在一起,然后得到这些锁后再操作,这就避免了整个工作空间的锁定: