java 无法理解线程行为

dfuffjeb  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(201)
  1. package safety.publishing;
  2. public class PublicStaticPublishing {
  3. public static void main(String[] args) {
  4. new Thread(new ReadRunnable()).start();
  5. new Thread(new WriteRunnable()).start();
  6. }
  7. }
  8. class A {
  9. public static int i = 0;
  10. }
  11. class ReadRunnable implements Runnable {
  12. int cache = A.i;
  13. @Override
  14. public void run() {
  15. for (;;) {
  16. if (A.i != cache) {
  17. System.out.println("cache miss " + A.i + " " + cache);
  18. cache = A.i;
  19. } else {
  20. // System.out.println("cache hit");
  21. }
  22. }
  23. }
  24. }
  25. class WriteRunnable implements Runnable {
  26. @Override
  27. public void run() {
  28. for (int i =0; i<1000; i++) {
  29. try {
  30. Thread.sleep(10);
  31. } catch (InterruptedException e) {
  32. }
  33. A.i++;
  34. }
  35. }
  36. }

字符串
有一个读取器线程和一个写入器线程。当ReadRunnable.run()方法的else块中的'println'语句被注解时,如上所示,由于我无法理解的原因,if块中的'println'语句也不会执行。控制台无限期保持空白。
但是,如果我在else块中取消注解'println',那么if和else块中的println语句都将打印如下所示。

  1. cache hit
  2. cache hit
  3. cache hit
  4. cache hit
  5. cache hit
  6. cache hit
  7. cache hit
  8. cache hit
  9. cache hit
  10. cache hit
  11. cache miss 222 221
  12. cache hit


我做错了什么?帮我弄明白到底发生了什么。

goqiplq2

goqiplq21#

在else块中取消注解println语句时,由于输出操作而引入延迟,在此期间,编写器线程(WriteRunnable)有机会更新A.i的值。因此,当在if语句中将cacheA.i进行比较时,根据写入器线程是否有机会更新A.i,打印“高速缓存未命中”或“高速缓存命中”消息。
然而,当你在else块中注解掉println时,并没有引入延迟,循环运行得非常快。在这种情况下,在执行if语句时,A.i的值可能还没有改变,导致else块被一致地执行,使控制台无限期地保持空白。

相关问题