为什么除非使用.join(),否则同步方法不会被锁定?

时间:2019-06-18 01:55:46

标签: java concurrency synchronized

Java中,标记方法synchronized应该禁用竞争条件,这是由于两个线程调用该方法而导致的,该线程正在访问和修改同一对象中的字段

但是由于某些原因,除非我在主程序的两个线程上调用synchronized,否则下一个示例中的.join()不能按预期工作。为什么会这样?

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

1 个答案:

答案 0 :(得分:0)

正如@flakes所阐明的那样,代码需要主线程进入join()两个线程,以确保两个线程都被终止,即对天平的修改,然后才打印出末尾{{1} }。

使用balance界面是实现此目的的更干净的方法。在这里,其java.util.concurrent.ExecutorService方法可确保线程池中的两个线程在打印结束shutdown()之前都已完成。这是我的实现:

balance