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();}但似乎是下一个线程来了…等待..但从未被通知..因为它从未醒来..我现在该怎么办?更新代码以便我的问题更清楚,通知似乎不起作用..也许我做得不对。。