簡體   English   中英

與調度程序一起使用時,線程進入同步塊

[英]Thread entering Synchronized block while used with Scheduler

我正在嘗試執行作業調度..盡管調度程序本身運行良好,但我想使用同步塊,以便沒有兩個作業可以同時運行(因為將存在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
}
}

問題是..以后要等待的線程要等待,但是被通知並不能使作業運行..或通知不能正常工作..我不知道..出了點問題..等待中的線程從不執行其工作..謝謝

看這段代碼:

new MyClass().executeMethod( ) 

現在,即使您已將executeMethod聲明為已同步,也將無法實現任何目的。 這是因為Java鎖(用於同步塊)是特定於對象的。 因此,使用相同MyClass實例的2個線程將被阻止,但是如果每個線程都有一個新的MyClass實例要處理,則不會。

因此,將新的MyClass()。executeMethod()替換為類似的內容

MyClass myClass =新的MyClass(); //僅在代碼中創建一次

每個線程應使用:

myClass.executeMethod()

這將有助於同步線程。

此代碼使用相同的參數:

ExecutingClass ec = new ExecutingClass ();

即使ExecutingClass的execute方法是同步的,也無法進行任何同步,因為每個線程都有自己的ExecutingClass實例要處理。 如果要同步,請在線程之間共享對象實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM