在Java
中,将方法标记为同步
应该禁用由于两个线程调用正在访问和修改的方法而导致的竞争条件同一对象中的字段。
但由于某种原因,除非我在主程序中的两个线程上调用 .join()
,否则 synchronized
在以下示例中无法按预期工作。这是为什么?
package example;
public class Account {
private double balance;
public Account(double balance) {
super();
this.balance = balance;
}
public synchronized void deposit(double amount) {
balance += amount;
}
public double getBalance() {
return balance;
}
}
package example;
public class AccountTester extends Thread {
private Account account;
private double amount;
public AccountTester(Account account, double amount) {
this.account = account;
this.amount = amount;
}
public static void main(String[] args) {
Account account = new Account(0);
AccountTester tester1 = new AccountTester(account, 1.0);
AccountTester tester2 = new AccountTester(account, 2.0);
tester1.start();
tester2.start();
// Why do I need the main thread to join threads
// tester1 and tester2 for synchronized to work?
try {
tester1.join();
tester2.join();
} catch (InterruptedException e) {
System.err.println(e);
}
System.out.println("End balance: " + account.getBalance());
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
account.deposit(amount);
}
}
}
最佳答案
正如@flakes所澄清的,代码需要主线程join()
两个线程来保证两个线程都终止,即在打印出之前完成对余额的修改结束余额
。
实现此目的的更简洁的方法是使用 java.util.concurrent.ExecutorService 接口(interface)。这里其 shutdown()
方法保证线程池中的两个线程在打印最终余额
之前完成。这是我的实现:
package example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AccountTester implements Runnable {
private Account account;
private double amount;
public AccountTester(Account account, double amount) {
this.account = account;
this.amount = amount;
}
public static void main(String[] args) {
Account account = new Account(0);
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new AccountTester(account, 1.0));
executorService.execute(new AccountTester(account, 2.0));
executorService.shutdown();
System.out.println("End balance: " + account.getBalance());
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
account.deposit(amount);
}
}
}
关于java - 为什么除非我使用 .join(),否则同步方法不会被锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56640820/