Java线程困惑,为什么输出没有顺序?

标签 java multithreading

查看输出,尽管使方法同步,但输出没有排序。由于两个线程都在堆上增加相同的对象“作业”,因此无论哪个线程打印该行,结果都应该是增加的值。但为什么打印的时候是乱码呢?

class TestSync implements Runnable{
  private int balance;

  public void run(){
    for(int i=0; i<50; i++) {
      increment();   
    System.out.println("balance is "+balance);
    }
  }
  public synchronized void increment(){
   balance++;     
  }
}


public class TestSyncTest {

  public static void main(String[] args){
    TestSync job = new TestSync();
    Thread a = new Thread(job);
    Thread b = new Thread(job);
    a.start();
    b.start();
  }
}

输出:

balance is 2
balance is 3
balance is 4
balance is 5
balance is 6
balance is 7
balance is 8
balance is 9
balance is 10
balance is 11
balance is 12
balance is 13
balance is 14
balance is 15
balance is 16
balance is 17
balance is 18
balance is 19
balance is 20
balance is 21
balance is 22
balance is 23
balance is 24
balance is 2
balance is 25
balance is 27
balance is 28
balance is 29
balance is 26
balance is 30
balance is 32
balance is 33
balance is 34
balance is 35
balance is 36
balance is 37
balance is 31
balance is 38
balance is 40
balance is 41
balance is 42
balance is 43
balance is 44
balance is 39
balance is 46
balance is 47
balance is 45
balance is 49
balance is 48
balance is 50
balance is 52
balance is 51
balance is 53
balance is 55
balance is 54
balance is 56
balance is 58
balance is 59
balance is 60
balance is 57
balance is 61
balance is 62
balance is 63
balance is 64
balance is 65
balance is 66
balance is 67
balance is 68
balance is 69
balance is 70
balance is 71
balance is 72
balance is 73
balance is 74
balance is 75
balance is 76
balance is 77
balance is 78
balance is 79
balance is 80
balance is 81
balance is 82
balance is 83
balance is 84
balance is 85
balance is 86
balance is 87
balance is 88
balance is 89
balance is 90
balance is 91
balance is 92
balance is 93
balance is 94
balance is 95
balance is 96
balance is 97
balance is 98
balance is 99
balance is 100

最佳答案

唯一同步的是增量。在打印变量之前读取变量不是,并且打印本身在另一个锁上同步。这样你就可以得到

  • 线程 1:增量
  • 线程 2:增量
  • 线程 1:读取并打印
  • 线程 2:读取并打印

顺便说一句,平衡是共享状态,并且所有访问(包括读取变量的值)应该在同一个锁上同步。

将代码更改为

class TestSync implements Runnable{
    private int balance;

    public void run(){
        for(int i = 0; i < 50; i++) {
            incrementAndPrint();   
        }
    }

    public synchronized void incrementAndPrint(){
        balance++;     
        System.out.println("balance is "+balance);
    }
}

关于Java线程困惑,为什么输出没有顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36514892/

相关文章:

Java Math.pow((1/(1+1),1) 无法正确计算

c - 我如何在 win32 平台上用 C 实现时间驱动的任务?

java - 维护单个执行程序服务并适当关闭它

c++ - 为什么在Release模式下的while循环中我无法逃脱?

python - 使用 threading.Timer 时 Ctrl-C 不起作用

python - 键盘同时中断多个线程

java - JDK7 中真的有 `ResultSet.getObject(String, Class<T>) 吗?

java - 在父类(super class)/子类框架中使用 ArrayLists

java - 计算合适的文本大小

java - Android 与 ReSTLet/JSON/Jackson 的兼容性