同步方法阻塞执行
Synchronized method blocks execution
我正在实施一个包含三个 class 的虚拟程序,以便更直观地了解 Future
的工作原理。我的问题是,有时程序会锁定在同步方法上,无法继续。我找不到原因。有人能找出 none 的战士打印“我赢了”行的原因吗?
阻塞时我的当前输出:
Fighter1
Fighter1 has entered the sync method
Fighter2
Fighter2 has entered the sync method
代码如下
主要class:
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:
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:
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!";
}
}
这与同步无关。每个战斗机在不同的对象上同步,因此它们不会相互干扰。
您看不到 "I won" 行的原因要简单得多——您从不打印它。
ClassWithSyncMethod#syncMethod()
方法(由 Fighter#call()
返回)不打印任何内容,它只是 returns 一个值。如果你想打印它,你必须自己从 main 打印它。
例如:
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();
}
}
我正在实施一个包含三个 class 的虚拟程序,以便更直观地了解 Future
的工作原理。我的问题是,有时程序会锁定在同步方法上,无法继续。我找不到原因。有人能找出 none 的战士打印“我赢了”行的原因吗?
阻塞时我的当前输出:
Fighter1
Fighter1 has entered the sync method
Fighter2
Fighter2 has entered the sync method
代码如下
主要class:
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:
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:
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!";
}
}
这与同步无关。每个战斗机在不同的对象上同步,因此它们不会相互干扰。
您看不到 "I won" 行的原因要简单得多——您从不打印它。
ClassWithSyncMethod#syncMethod()
方法(由 Fighter#call()
返回)不打印任何内容,它只是 returns 一个值。如果你想打印它,你必须自己从 main 打印它。
例如:
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();
}
}