【问题标题】:Java Synchronized account example isn't working as expectedJava 同步帐户示例未按预期工作
【发布时间】:2021-12-27 08:27:05
【问题描述】:

我正在使用 Account 示例来练习 Java Synchronized。
这是我的代码。

帐户类别

class Account {

public int dollars;

public Account(int d) {
    dollars = d;
}

// might fail due to concurrently accessing this method
public synchronized void deduct2(int amount) {
      dollars -= amount;
}

@Override
public String toString() {
    return "" + dollars;
}

MyThread 类

 class MyThread extends Thread {
static Account account = new Account(10000);

private int id;

public MyThread(int i) {
    id = i;
}

@Override
public void run() {
    System.out.println("performing my job ....");
    for (int i = 0; i < 100; i++) {
        account.deduct2(1);
        System.out.println("account " + account + "  " + getName() +"performing....");
    }
}

ThreadTest 类

public class ThreadTest {

public static void main(String args[]) {
    new ThreadTest().exec();
    System.out.println("main finished");
}

private void exec() {
    test1();
}

private void test1() {
    Thread thread1 = new MyThread(1);
    Thread thread2 = new MyThread(2);
    Thread thread3 = new MyThread(3);
    thread1.start();
    thread2.start();
    thread3.start();

}}

结果

主要完成
执行我的工作....
执行我的工作....
执行我的工作....
帐号 9997 Thread-0 正在执行....
帐户 9997 线程 2 正在执行....
帐户 9997 线程 1 正在执行....
帐户 9995 线程 2 正在执行....
帐号 9996 Thread-0 正在执行....
帐户 9993 线程 2 正在执行....
帐户 9994 线程 1 正在执行....
帐户 9991 线程 2 正在执行....
帐号 9992 Thread-0 正在执行....
帐户 9989 线程 2 正在执行....
帐号 9990 Thread-1 正在执行....
帐户 9987 线程 2 正在执行....
帐号 9988 Thread-0 正在执行....
帐户 9985 线程 2 正在执行....
帐户 9986 线程 1 正在执行....
....
帐户 9713 Thread-1 正在执行....
帐户 9708 Thread-1 正在执行....
帐户 9709 Thread-0 正在执行....
帐号 9706 Thread-0 正在执行....
帐户 9707 Thread-1 正在执行....
帐号 9704 Thread-1 正在执行....
帐号 9705 Thread-0 正在执行....
帐号 9702 Thread-0 正在执行....
帐户 9703 线程 1 正在执行....
帐号 9701 Thread-0 正在执行....
account 9700 Thread-1performing....

我跑了三个不同的新线程,每个新线程减1一百次。所以帐户美元的结果是正确的(9700)。
但我很困惑为什么扣除账户美元的过程没有按我的预期工作。我认为它会像 9999 9998 9997 一样运行.....

【问题讨论】:

  • 因为您的打印语句不是任何同步的一部分,所以它可以查看任何值。
  • 谢谢!我现在知道问题出在哪里了。
  • 然后考虑接受你得到的答案;-)

标签: java multithreading synchronized


【解决方案1】:

您的System.out.println 未同步,例如:

  1. 一开始dollers是10000 , thread1thread2 执行 account.deduct2(1);现在dollers是9998。
  2. thread3执行account.deduct2(1);现在dollers是9997。
  3. thread1thread2 开始打印account#dollars,你会看到两个9997

如果要顺序打印,请将synchronized放入for循环中。(Account#deduct2不再需要添加synchronized。):

       for (int i = 0; i < 100; i++) {
            synchronized (account) {
                account.deduct2(1);
                System.out.println("account " + account + "  " + getName() + "performing....");
            }
        }

【讨论】:

  • 感谢您的回答!我想知道这个问题有一段时间......你们帮了我很多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 2020-03-08
相关资源
最近更新 更多