我正在尝试进行作业调度..虽然调度程序本身运行良好,但我想使用一个synchronized块,这样就不会同时运行两个作业(因为会出现DB Access并发问题)。但不幸的是,等待工作没有在通知
上醒来以下是使用的代码:用于作业监听器
public class SJobListener implements JobListener {
public static final String LISTENER_NAME = "SJobListener";
ExecutingClass ec = new ExecutingClass ();
@Override
public String getName() {
return LISTENER_NAME; //must return a name
}
// Run this if job is about to be executed.
@Override
public void jobToBeExecuted(JobExecutionContext context) {
String jobName = context.getJobDetail().getKey().toString();
System.out.println("jobToBeExecuted");
System.out.println("Listener : Job : " + jobName + " is going to start...");
System.out.println("Thread running in jobToBeExecuted :"+Thread.currentThread().getName()+" "+Thread.currentThread().getId());
synchronized (ec) {
System.out.println(Thread.currentThread().getName());
System.out.println("SYNCHRONIZED BLOCK"+jobName);
if(!condition){
try {
System.out.println("Going to Wait");
Thread.currentThread().wait(200);
//check the condition again
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//ec .execute(context); as scheduler automatically calls this method, explicitly calling it runs the method twice , one by scheduler and the other executed explicitly
}
//}
//Run this after job has been executed
@Override
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException) {
System.out.println("jobWasExecuted");
String jobName = context.getJobDetail().getKey().toString();
System.out.println("Listener :Job : " + jobName + " is finished...");
System.out.println("Thread running in jobWasExecuted :"+Thread.currentThread().getName()+" "+Thread.currentThread().getId());
/*String testCaseName = context.getJobDetail().getDescription();
QueryBuilderUtil.updateRecordInSchedular(testCaseName,"completed");*/
if (!jobException.getMessage().equals("")) {
System.out.println("Exception thrown by: " + jobName
+ " Exception: " + jobException.getMessage());
jobException.printStackTrace();
}
Thread.currentThread().notifyAll();
}
以下是ExecutingClass的代码
public class ExecutingClass implements Job{
private MyClass mc = new MyClass();
public synchronized void execute(JobExecutionContext context) {
try
{
System.out.println("--------execute------ "+context.getJobDetail().getKey());
System.out.println("--------Current Thread------ "+Thread.currentThread().getName()+" "+Thread.currentThread().getId());
mc .executeMethod( );
System.out.println("Done MyClass.executeTestCase");
}
catch (BusinessException e) {
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
以下是MyClass的代码
public class MyClass(){
public synchronized void executeMethod( ){
//does the actual processing i.e read write from DB
}
}
问题是......之后的线程会等待,但是通知并不会使作业运行..或者通知不起作用..我不知道......有什么不对......等待线程永远不会完成它的工作。 。 感谢
答案 0 :(得分:0)
看看这段代码:
new MyClass().executeMethod( )
现在即使你已经将executeMethod声明为synchronized,它也没有任何意义。那是因为Java锁(对于synchronized块)是特定于对象的。因此,使用相同MyClass实例的2个线程将阻塞,但如果每个线程都有一个新的MyClass实例要处理,则它们不会。
所以用
之类的东西替换新的MyClass()。executeMethod()MyClass myClass = new MyClass(); //在代码中只创建一次
每个帖子应该使用:
myClass.executeMethod()
这将有助于同步线程。
这段代码也是如此:
ExecutingClass ec = new ExecutingClass ();
即使ExecutingClass的execute方法是同步的,它也无助于任何同步,因为每个线程都有自己的ExecutingClass实例来处理。如果要进行同步,请在线程之间共享对象实例。