2017-10-08 81 views
-1

我認爲Java中的同步方法是一次執行一次。 但是,我看到如果2個可調用函數正在通過同步塊,它們將並行執行。Java可調參數不同步

這是我的固定線程池的Executor類。

public class ThreadExecutor 
{ 

    ExecutorService executors = Executors.newFixedThreadPool(100); 
    public void callCallable2() 
    { 
     System.out.println("Inside executor callable 2 method"); 
     ThreadTestCallable2 t = new ThreadTestCallable2(); 
     executors.submit(t); 
     System.out.println("Exiting executor callable 2 method"); 
    } 

    public void callCallable1() 
    { 
     System.out.println("Inside the executor callable 1 method"); 
     ThreadTestCallable1 t = new ThreadTestCallable1(); 
     executors.submit(t); 
     System.out.println("exiting the executor callable 1 method"); 
    } 

} 

我可調用的類是:

public class ThreadTestCallable1 implements Callable { 

    @Override 
    public Object call() throws Exception { 
     System.out.println("Inside the threadtestcallable 1"); 
     ThreadHelperTest t = new ThreadHelperTest(); 
     t.test(); 
     System.out.println("Exiting the threadtestcallable 1"); 
     return null; 
    } 

} 

public class ThreadTestCallable2 implements Callable{ 

    @Override 
    public Object call() throws Exception { 
     System.out.println("Inside the threadtestcallable 2"); 
     ThreadHelperTest t = new ThreadHelperTest(); 
     t.test(); 
     System.out.println("exitting the threadtestcallable 2"); 
     return null; 
    } 


} 

我調用同步方法是在輔助類。

public class ThreadHelperTest 
{ 
    public void test() 
    { 
     test1(); 
    } 

    public synchronized void test1() 
    { 
     try { 
      System.out.println("Sleeping for 10 sec's T-name: "+ 
      Thread.currentThread().getName()); 
      Thread.sleep(60000); 
      System.out.println("wokeup T-Name: "+ 
      Thread.currentThread().getName()); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

這裏是我的主類:

public class ThreadTest { 

    public static void main(String arg[]){ 

     ThreadExecutor t = new ThreadExecutor(); 
     t.callCallable1(); 
     t.callCallable2(); 
    } 

} 

爲上述執行最終輸出是我看到的可調用對象進入的時間同步方法,這是不應該的,什麼毛病監視對象。?

請找到上述代碼的結果:

Inside the executor callable 1 method 
exiting the executor callable 1 method 
Inside executor callable 2 method 
Inside the threadtestcallable 1 
Exiting executor callable 2 method 
Inside the threadtestcallable 2 
Sleeping for 10 sec's T-name: pool-1-thread-1 
Sleeping for 10 sec's T-name: pool-1-thread-2 
wokeup T-Name: pool-1-thread-1 
Exiting the threadtestcallable 1 
wokeup T-Name: pool-1-thread-2 
exitting the threadtestcallable 2 

如果有什麼需要改變,請給我建議。 以獲得這些方法的同步。

+0

我懷疑這裏的問題是創建新的對象,從而爲兩個對象創建兩個不同的監視器。 如果這種情況下,請提出任何替代計劃,以實現可卡拉之間的同步。 –

+0

'ThreadTestCallable1'和'ThreadTestCallable2'必須有一個字段'ThreadHelperTest t'。然後,您創建可調用對象並傳入'ThreadHelperTest'的同一個實例。 – luk2302

+0

這裏的問題是肯定**,你有多個ThreadHelperTest實例。規則是一個非靜態的'synchronized'在同一個實例*上提供對其他'同步'調用*的排除。你有不同的實例。因此在關係之前不會互相排斥,也不會發生同步。 –

回答

0

您的每個可調用對象都有自己的ThreadHelperTest實例。允許對不同實例的synchronized method進行交織。

首先,它是不可能的同步方法兩次調用上同一對象交織。

您可以將ThreadHelperTest的相同實例傳遞給您的可調用對象,或使用任何其他共享互斥對象進行同步。

+0

任何使用Util.Concurrent.Locks的機會..? 需要做些什麼才能實現這兩個可調參數之間的同步。 有什麼想法。? 我實際上也嘗試過鎖定機制,但這些也不工作,使用靜態字段進行同步的任何想法。 –

+0

@AnilkumarPVV一切都在答案中。你並不需要'java.util.concurrent.locks',只是在共享的東西上進行同步。 – lexicore