[英]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.