gpt4 book ai didi

java - 寻找竞争条件

转载 作者:行者123 更新时间:2023-11-30 04:11:21 25 4
gpt4 key购买 nike

有人可以解释一下这段代码中的竞争条件在哪里吗?我的讲师设置了它,但我还不完全理解如何发现它们,或者说为什么给出的结果会发生。

public class SlowRace {

public static void main(String args []) throws Exception {

MyThread.count = 0 ;

MyThread thread1 = new MyThread() ;
thread1.name = "A" ;

MyThread thread2 = new MyThread() ;
thread2.name = "B" ;

thread1.start() ;
thread2.start() ;

thread2.join() ;
thread1.join() ;

System.out.println("MyThread.count = " + MyThread.count) ;
}
}

class MyThread extends Thread {

volatile static int count ;

String name ;

public void run() {

for(int i = 0 ; i < 10 ; i++) {
delay() ;
int x = count ;
System.out.println("Thread " + name + " read " + x) ;
delay() ;
count = x + 1;
System.out.println("Thread " + name + " wrote " + (x + 1)) ;
}
}

static void delay() {

int delay = (int) (1000000000 * Math.random()) ;
for(int i = 0 ; i < delay ; i++) {}
}
}

返回的结果:

Thread A read 0
Thread A wrote 1
Thread B read 0
Thread A read 1
Thread B wrote 1
Thread A wrote 2
Thread B read 2
Thread A read 2
Thread B wrote 3
Thread A wrote 3
Thread B read 3
Thread A read 3
Thread B wrote 4
Thread A wrote 4
Thread B read 4
Thread A read 4
Thread B wrote 5
Thread A wrote 5
Thread B read 5
Thread A read 5
Thread B wrote 6
Thread A wrote 6
Thread B read 6
Thread A read 6
Thread B wrote 7
Thread A wrote 7
Thread B read 7
Thread A read 7
Thread B wrote 8
Thread A wrote 8
Thread B read 8
Thread A read 8
Thread B wrote 9
Thread A wrote 9
Thread B read 9
Thread A read 9
Thread B wrote 10
Thread A wrote 10
Thread B read 10
Thread B wrote 11
MyThread.count = 11

最佳答案

Hey guys could someone explain where the race condition is in this piece of code,

比赛就在这两条线之间:

          int x = count ;
...
count = x + 1;

一个线程获取该值,但另一个线程可以在第一个线程使用递增的值更新该值之前获取相同的值。这就是比赛。

  1. thread-1 获取count 的值并将其存储在x 中。 x 是(假设是 10)。
  2. 同时,thread-2 也获取 count 的值并将其存储在 x 中。 x 是(假设是 10)。
  3. thread-1 将 x 增加到 11 并将其存储回 count
  4. thread-2 将其 x 副本递增为 11 并将其存储回 count ——这会覆盖 thread-1 的增量.

因此,count 不再是 12,而是会丢失其中一个增量,从而变为 11。

练习是为了指出增量不是原子的。实际上,delay() 是没有必要的。 count++ 也会证明这个问题,因为它不是原子的(获取/增量/设置),并且线程可以在 3 个操作中间中断。

使此代码变得复杂的一件事是 System.out.println(...) 是同步的,因此控制台输出将改变程序的计时。

关于java - 寻找竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19546145/

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