Java 与调度程序一起使用时线程进入同步块
我正在尝试进行作业调度。虽然调度程序本身运行良好,但我希望使用一个同步块,这样就不会有两个作业同时运行(因为会出现数据库访问并发问题)。但不幸的是,等待的工作并没有及时醒来 下面是用于作业侦听器的代码Java 与调度程序一起使用时线程进入同步块,java,multithreading,quartz-scheduler,synchronized,Java,Multithreading,Quartz Scheduler,Synchronized,我正在尝试进行作业调度。虽然调度程序本身运行良好,但我希望使用一个同步块,这样就不会有两个作业同时运行(因为会出现数据库访问并发问题)。但不幸的是,等待的工作并没有及时醒来 下面是用于作业侦听器的代码 public class SJobListener implements JobListener { public static final String LISTENER_NAME = "SJobListener"; ExecutingClass ec = new Execut
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
}
}
问题是..稍后出现的线程将等待,但通知不会使作业运行..或者可能通知不起作用。。我不知道……出了什么问题……等待的线程从不工作。。
谢谢看下面的代码:
new MyClass().executeMethod( )
现在,即使您已将executeMethod声明为synchronized,它也不会有任何作用。这是因为Java锁(用于同步块)是特定于对象的。因此,使用同一MyClass实例的两个线程将被阻塞,但如果每个线程都有一个新的MyClass实例要处理,它们就不会被阻塞
因此,将新的MyClass().executeMethod()替换为
MyClass MyClass=新建MyClass();//只在代码中创建一次
每个线程都应该使用:
myClass.executeMethod()
这将有助于同步线程
此代码也有相同的参数:
ExecutingClass ec = new ExecutingClass ();
尽管ExecutingClass的execute方法是同步的,但它对任何同步都没有帮助,因为每个线程都有自己的ExecutingClass实例要处理。如果需要同步,请在线程之间共享对象实例。您在实例上执行同步的方法,在类上执行作业。这是有意的吗?很抱歉,没有像您所说的那样获得QueryId,同步了对象而不是类,但它仍在执行twiceI。我看到您每次都在SJobListener中创建一个新的ec实例,所以这不起作用。在“上下文”上进行同步怎么样。看起来该对象是在ExecutingClass和JobListener之间传递的。也尝试过这样做。但没有帮助。不,我没有在ExecutingClass和JobListenerok之间传递任何对象,谢谢,我现在共享MyClass的一个实例..和Executing class的一个实例..并保留在jobToBeExecuted()方法中:代码为synchronized(ec){while(!condition)Thread.currentThread.wait()},而在jobWasExecuted中代码为synchronized(ec){Thread.currentThread.notifyAll();}但似乎是下一个线程来了…等待..但从未被通知..因为它从未醒来..我现在该怎么办?更新代码以便我的问题更清楚,通知似乎不起作用..也许我做得不对。。