当前位置: 首页 > 知识库问答 >
问题:

Java同步帐户示例没有按预期工作

宋耀
2023-03-14
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;
}
 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线程-0执行....
帐户9997线程-2执行....
帐户9995线程-1执行....
帐户9993线程-2执行....
帐户9994线程-1执行....
帐户9992线程-1执行....
帐户9992线程-1执行....
帐户9992线程-2执行....
帐户9992线程-2执行....
帐户9989线程-2执行....2执行...
帐户9988线程-0执行...
帐户9985线程-2执行...
帐户9986线程-1执行...
...
帐户9713线程-1执行...
帐户9708线程-1执行...
帐户9709线程-0执行...
帐户9706线程-0执行...
帐户9707线程-1执行...
帐户9707线程-1执行...
帐户9704线程-1执行...
帐户9704线程-1执行...
帐户9705线程-0执行....
帐户9702线程-0执行....
帐户9703线程-1执行....
帐户9701线程-0执行....
帐户9700线程-1执行....

我运行三个不同的新线程,每个新线程100次扣1。所以帐户美元的结果是正确的(9700)。
但我很困惑为什么账户美元被扣除的过程没有像我预期的那样工作。我想它会像9999 999 8 999 7......

共有1个答案

卫招
2023-03-14

您的system.out.println不同步,例如:

  1. 开始时dollers是10000,线程1线程2执行帐户扣减2(1);现在dollers是9998。
  2. 线程3执行帐户扣减2(1);现在dollers是9997。
  3. 线程1线程2开始打印帐户#美元,您将看到两个9997.

如果要按顺序打印,请将synchronized放入for循环。(帐户#duct2不再需要添加synchronized。):

       for (int i = 0; i < 100; i++) {
            synchronized (account) {
                account.deduct2(1);
                System.out.println("account " + account + "  " + getName() + "performing....");
            }
        }
 类似资料:
  • 我在使用R的group_by和SUMMARY函数时遇到了一些问题,我想知道你们是否可以帮我一些忙。我有一张类似的表格: 我试图使用dplyr的group_by和SUMMARY来找到频率列的平均值。下面是我的示例代码: 我所期望的是,一个表格被吐出来,分解按单个类别分组的平均频率,如下所示: 但是,我收到的是一个按类别分组的表,每个类别接收整个表的平均值,如下所示: 有什么线索吗?我应该说我是初学者

  • 我已经配置了log4j2.xml文件,application.log文件将被创建,它应该每天翻转。 但是在JVM中,applicatoin.log文件在10MB之后会翻转,如果翻转三次,第一个文件会被覆盖。也就是说我随时都application.logapplication-2020-10-16.log.zip. 为什么log4j2(v2.13)即使配置为每日,也会每10MB滚动一次文件?任何在l

  • 现在,在我的drools项目中,我在单独的DRL文件中有两组规则,它们由议程组分割。对于议程组“preCheck”,我将该议程组中的每个规则的自动聚焦设置为true。例子: 对于另一个议程组-“default规则”-规则没有设置自动焦点属性。示例: 在通过RESTAPI调用规则时,我还试图通过JSON负载将焦点设置为“preCheck”议程组。例子: 然而,在执行规则时,似乎首先要评估“defau

  • 我正试图将一个阻塞消费者集成为Reactor铝-SR1中的助焊剂订户。我想使用一个并行调度器,并发地执行阻塞操作。 我实现了一个主类来描述我意图:

  • 问题内容: 谁能解释两个我为什么这些代码不输出相同的结果(两个代码之间的唯一区别是run()方法)? 注意:第一个代码似乎没有做任何锁定! 第一个代码: 第二个代码: 该代码完全按照预期工作 问题答案: 第一码 事实是,您有3个线程实例,每个线程运行它自己的method实例。但是总是只有一个线程想要与其自己的方法同步,因此它将在线程希望其运行时运行。这根本没有同步。 第二码 您也有3个线程实例,但

  • 我目前正在使用Cucumber和Java开发一个基于Selenium的BDD测试自动化框架。我的框架使用Junit,由于Junit不支持软断言,所以我尝试在测试中使用AssertJ断言。然而,这些断言似乎不起作用。让我试着借助下面的代码来解释这一点: