2014-09-25 2 views
2

Я пытаюсь выполнить планирование работы. В то время как планировщик сам по себе работает нормально, я хотел использовать синхронизированный блок, чтобы одновременно не запускать два задания (так как будет доступ к БД проблемы параллелизма). Но, к сожалению, работа ожидания не просыпаясь на извещатьВвод нити Синхронизированный блок при использовании с планировщиком

Ниже приведен код, используемый: для работы слушателя

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 
} 
} 

Проблема в том, что потоки, идущие позже, идут ждать, но не являются FY не делает работу run..or возможно уведомлять не работает .. Я не know..something wrong..the ожидающего нить никогда не делает свою работу .. Благодаря

+0

Вы выполняете метод 'execute', синхронизированный в экземпляре, и' jobToBeExecuted' на классе. Он предназначен? – talex

+0

извините, не получил запрос – user2176576

ответ

0

Посмотрите на этот код:

new MyClass().executeMethod() 

Теперь, даже если вы объявили executeMethod как синхронизированный, он не достигнет цели. Это связано с тем, что блокировка Java (для синхронизированного блока) специфична для объекта. Таким образом, 2 потока, которые используют один и тот же экземпляр MyClass, будут блокироваться, но если у каждого потока есть новый экземпляр MyClass, он не будет.

Так заменить новый MyClass() ExecuteMethod() с чем-то вроде

MyClass MyClass = нового MyClass(). // создать только один раз в коде

И каждый поток должен использовать:

myClass.executeMethod()

Это поможет в синхронизации потоков.

Тот же самый аргумент идет для этого кода:

ExecutingClass ec = new ExecutingClass(); 

Даже если выполнить метод ExecutingClass синхронизируется, это не помогает с любой синхронизацией, поскольку каждый поток имеет собственный экземпляр ExecutingClass иметь дело. Если вы хотите синхронизировать, обменивайтесь экземпляром объекта между потоками.

+0

сделал, как вы сказали, синхронизировал объект вместо класса, но его выполнение дважды – user2176576

+0

Я вижу, что вы каждый раз создаете новый экземпляр ec в SJobListener, так что это не сработает. Как насчет синхронизации по «контексту». Похоже, что этот объект передается между ExecutingClass и JobListener. – SJha

+0

Пробовал делать это тоже .. но это не помогло. Нет. Я не передаю какой-либо объект между ExecutingClass и JobListener. – user2176576

Смежные вопросы