2017-08-28 115 views
1

我正在實現一個帶有三個類的虛擬程序,以更直觀地參考Future的工作方式。我的問題是,有時程序將被鎖定在同步方法,它不會繼續。我找不到原因。有人能夠發現爲什麼沒有一個戰士會打印「我贏了」的路線嗎?當塊同步方法塊執行

我的電流輸出:

Fighter1

Fighter1已進入同步方法

Fighter2

Fighter2已進入同步方法

的代碼如下。

主要類:

import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 

public class TmpTest { 
private static final ExecutorService executorService = 
    Executors.newFixedThreadPool(2); 

    public static void main(final String... args) { 

    final Fighter fighter1 = new Fighter("Fighter1"); 
    final Fighter fighter2 = new Fighter("Fighter2"); 

    final Future<String> submitFighter1 = executorService.submit(fighter1); 
    final Future<String> submitFighter2 = executorService.submit(fighter2); 

    while (!submitFighter1.isDone() || !submitFighter2.isDone()) { 
     if (submitFighter1.isDone()) { 
      System.out.println("Fighter 1 wins!"); 
      submitFighter2.cancel(true); 
      executorService.shutdown(); 
     } else if (submitFighter2.isDone()) { 
      submitFighter1.cancel(true); 
      System.out.println("Fighter 2 wins!"); 
      executorService.shutdown(); 
     } 
    } 
    } 
} 

戰鬥機類:

class Fighter implements Callable<String> { 

    private final String fighterName; 
    private final ClassWithSyncMethod classWithSyncMethod; 

    public Fighter(final String fighterName) { 
    this.fighterName = fighterName; 
    classWithSyncMethod = new ClassWithSyncMethod(fighterName); 
    } 

    @Override 
    public String call() throws Exception { 
    return classWithSyncMethod.syncMethod(); 
    } 
} 

虛擬類synchronized方法:

class ClassWithSyncMethod { 

    private final String fighterName; 

    public ClassWithSyncMethod(final String fighterName) { 
    this.fighterName = fighterName; 
    } 

    public synchronized String syncMethod() { 
    System.out.println(fighterName + " has entered the sync method"); 
    try { 
     Thread.sleep(1000); 
    } catch (final InterruptedException e) { 
     System.out.println("Exception trying to sleep the fighter " + fighterName + ";" + e); 
    } 
    return fighterName + " shouts: I won!"; 
    } 
} 

回答

3

這有什麼好做同步。每個戰鬥機在不同的物體上同步,所以它們不會相互干擾。

您看不到「我贏了」這一行的原因要簡單得多 - 您永遠不會打印它。 ClassWithSyncMethod#syncMethod()方法(由Fighter#call()返回)不會打印任何內容,它只是返回一個值。如果你想打印它,你必須自己去打印。

例如爲:

while (!submitFighter1.isDone() || !submitFighter2.isDone()) { 
    if (submitFighter1.isDone()) { 
     System.out.println("Fighter 1 wins!"); 
     System.out.println(submitFighter1.get()); // Here! 
     submitFighter2.cancel(true); 
     executorService.shutdown(); 
    } else if (submitFighter2.isDone()) { 
     submitFighter1.cancel(true); 
     System.out.println("Fighter 2 wins!"); 
     System.out.println(submitFighter2.get()); // And here! 
     executorService.shutdown(); 
    } 
} 
+0

你是絕對正確的。我是個白癡。謝謝! – Tavo

+1

右鍵點'每個戰士在不同的物體上同步',爲你+1 –