同步方法阻止执行

时间:2017-08-28 08:24:17

标签: java future executorservice synchronized

我实现了一个包含三个类的虚拟程序,以便更加直观地了解Future的工作方式。我的问题是,有时程序将被锁定在同步方法,它不会继续下去。我无法找到原因。有人可以找出为什么没有战士打印出来的原因,我赢了#34;线?

阻止时的当前输出:

  

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

使用同步方法的虚拟类:

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!";
  }
}

1 个答案:

答案 0 :(得分:2)

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

你没有看到&#34;我赢了&#34;线条更简单 - 你永远不会打印它。 ClassWithSyncMethod#syncMethod()方法(由Fighter#call()返回)不打印任何内容,只返回一个值。如果您想要打印它,您必须自己从主打印。

E.g:

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