Java 同步方法阻止执行

Java 同步方法阻止执行,java,future,executorservice,synchronized,Java,Future,Executorservice,Synchronized,我正在实现一个包含三个类的虚拟程序,以便更直观地了解未来的工作方式。我的问题是,有时程序会被锁定在synchronized方法上,而无法继续。我找不到原因。有人能找出为什么没有一个战士会打印“我赢了”这一行的原因吗 阻塞时的当前输出: 战斗1 Fighter1已输入同步方法 战斗2 Fighter2已输入同步方法 代码如下 主要类别: import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService

我正在实现一个包含三个类的虚拟程序,以便更直观地了解
未来的工作方式。我的问题是,有时程序会被锁定在synchronized方法上,而无法继续。我找不到原因。有人能找出为什么没有一个战士会打印“我赢了”这一行的原因吗

阻塞时的当前输出:

战斗1

Fighter1已输入同步方法

战斗2

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();
        }
    }
  }
}

这与同步无关。每架战斗机在一个不同的物体上同步,所以它们不会相互干扰

你看不到“我赢了”这行的原因要简单得多——你从不打印它。
ClassWithSyncMethod#syncMethod()
方法(由
Fighter#call()
返回)不打印任何内容,只返回一个值。如果你想打印它,你必须自己从主屏幕开始打印

例如:


右关键点
每架战斗机在不同的目标上同步
,+1
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();
  }
}
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!";
  }
}
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();
    }
}