gpt4 book ai didi

Java 同步方法和 block

转载 作者:行者123 更新时间:2023-12-02 07:30:05 24 4
gpt4 key购买 nike

我试图更全面地了解 Java 中多线程的同步。我了解使用synchronized关键字背后的高级思想,以及它如何在线程之间提供互斥。

唯一的事情是,即使您删除了synchronized关键字,我在网上和教科书中阅读的大多数示例仍然可以正常工作,这使得这个主题比我想象的更加令人困惑。

任何人都可以为我提供一个具体的例子,说明何时不包含同步关键字会产生错误的结果?任何信息将不胜感激。

最佳答案

您通常可以通过增加迭代次数来触发竞争条件。这是一个简单的示例,可以进行 100 次和 1,000 次迭代,但在 10,000 次迭代(有时)时失败(至少在我的四核机器上)。

public class Race
{
static final int ITERATIONS = 10000;
static int counter;

public static void main(String[] args) throws InterruptedException {
System.out.println("start");
Thread first = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
Thread second = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
first.start();
second.start();
first.join();
second.join();
System.out.println("Counter " + counter + " should be " + (2 * ITERATIONS));
}
}

>>> Counter 12325 should be 20000

此示例失败,因为对 counter 的访问未正确同步。它可能会以两种方式失败,可能在同一次运行中都失败:

  • 一个线程无法看到另一个线程已递增计数器,因为它没有看到新值。
  • 一个线程在另一个线程读取当前值和写入新值之间递增计数器。这是因为递增和递减运算符不是原子的。

这个简单程序的修复方法是使用 AtomicInteger。由于增量的问题,使用 volatile 是不够的,但是 AtomicInteger 提供了增量、获取和设置等原子操作。

关于Java 同步方法和 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13021256/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com