【问题标题】:Method synchronization issue. Java方法同步问题。爪哇
【发布时间】:2015-11-19 10:17:05
【问题描述】:

我正在尝试理解 Java 中的多线程,但遇到了以下问题: 我创建了 20 个线程,每个线程执行一个简单的递增操作并获取一些值。请在下面找到代码摘录:

public class MyClass {

public static void main(String[] args) {

  for (int i = 0 ; i < 20 ; i ++) {
     new Thread(() -> {
        System.out.println(Thread.currentThread().getName() + " == " + MyClass1.incAndGet());
     }).start();
  }

}

private static class MyClass1 {

  static private int s;

  private static synchronized int incAndGet(){
     return s ++;
  }

 }
}

这里对incAndGet方法的访问是同步的,因此没有线程可以在不一致的线程中找到s变量的状态。我无法理解的是为什么输出如下:

Thread-0 == 2
Thread-11 == 10
Thread-14 == 12
Thread-15 == 9
Thread-18 == 14
Thread-13 == 8
....

不应该是这样的:

Thread-0 == 0
Thread-11 == 11
Thread-14 == 14
Thread-15 == 15
Thread-18 == 18
Thread-13 == 13
....

如果我误解了同步的概念,请您提供同步的好和坏的例子。谢谢。

【问题讨论】:

    标签: java multithreading synchronization


    【解决方案1】:

    不保证线程将以顺序方式执行。 在不同的运行中,它会显示不同的输出。

    【讨论】:

      【解决方案2】:

      数字不匹配,因为调度程序运行线程的顺序与创建它们的顺序不同。线程名称在创建时确定,而编号s 在线程实际运行时计算。

      【讨论】:

        【解决方案3】:

        在您的线程作业中,通常有两个基本操作:incAndGet()System.out.println()。此操作的顺序也不是连续的:例如Thread-13 可以执行incAndGet,然后Thread-18 将执行incAndGet,然后Thread-18 将执行System.out.println(),然后是Thread-13。因此,如果您想要连续打印输出,您应该将 incAndGetprintln 同步:

          synchronized (MyClass.class) {
                            System.out.println(Thread.currentThread().getName() + " == " + MyClass1.incAndGet());
                        }
        

        【讨论】:

        • 这不会阻止线程以不同于启动顺序的顺序打印。
        猜你喜欢
        • 2015-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-30
        • 2015-05-23
        • 1970-01-01
        • 2019-09-13
        相关资源
        最近更新 更多