2014-09-25 21 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 2014-09-25 12:16:47

+0

對不起,沒有得到查詢 – user2176576 2014-09-25 12:31:22

回答

0

看看這段代碼:

new MyClass().executeMethod() 

現在即使你已經聲明executeMethod爲synchronized,它也不會達到目的。這是因爲Java鎖(用於同步塊)是特定於對象的。因此,使用MyClass的相同實例的2個線程將會阻塞,但是如果每個線程都有一個新的MyClass實例需要處理,它們將不會。

所以的東西替換新MyClass的()executeMethod()之類

MyClass的MyClass的=新MyClass的()。 //代碼

創建只有一次,每個線程應使用:

myClass.executeMethod()

這將同步線程幫助。

同樣的道理也適用於這樣的代碼:

ExecutingClass ec = new ExecutingClass(); 

即使執行ExecutingClass的方法是同步的,它不與任何同步幫助,因爲每個線程都有它ExecutingClass的自己的實例來處理。如果你想同步,在線程之間共享對象實例。

+0

沒有像你所說的,同步對象而不是類,仍然執行兩次 – user2176576 2014-09-25 12:30:49

+0

我看到你每次都在SJobListener中創建一個新的ec實例,所以這是行不通的。在「上下文」上同步怎麼樣?它看起來像是在ExecutingClass和JobListener之間傳遞的。 – SJha 2014-09-25 12:35:15

+0

試過這樣做也..但它沒有幫助。不,我沒有在ExecutingClass和JobListener之間傳遞任何對象 – user2176576 2014-09-25 12:47:23