java - 多线程中的同步块(synchronized block)

标签 java multithreading

我有一个方法,调用该方法的 2 个 synchronize block ,并提供了代码,

    private static int count1 = 0;
    private static int count2 = 0;

    public synchronized static void add() {
    count1++;
    System.out.println("T name: " + Thread.currentThread().getName()
    + "count1 = " + count1);
}

public synchronized static void addAgain() {
    count2++;
    System.out.println("T name: " + Thread.currentThread().getName()
            + "count1 = " + count2);
}

    public static void compute() {
        for(int i=0;i<100;++i) {
            add();
            addAgain();
        }
    }

这里我们定义了 2 个线程,并从每个线程中调用 compute 方法。下面提供了代码片段,

        Thread t1 = new Thread(() -> compute());
        Thread t2 = new Thread(() -> compute());

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

根据提供的代码,我有三个问题:

  1. 当线程调用compute方法时,它是否可以访问内部的两个synchronized方法并执行增量操作?

  2. 如果一个线程访问 for 循环,它会完成 for 循环还是在竞争之前将其保留以与其他线程共享?

  3. 如果是这种情况,我假设另一个线程处于等待阶段并且不做太多事情。这是正确的吗?

为了讨论,这是我运行后得到的结果:

    Thread name: Thread-0  count1 value = 1
Thread name: Thread-1  count1 value = 2
Thread name: Thread-1 count2 value = 1
Thread name: Thread-1  count1 value = 3
Thread name: Thread-1 count2 value = 2
Thread name: Thread-1  count1 value = 4
Thread name: Thread-1 count2 value = 3
Thread name: Thread-1  count1 value = 5
Thread name: Thread-1 count2 value = 4
Thread name: Thread-1  count1 value = 6
Thread name: Thread-1 count2 value = 5
Thread name: Thread-1  count1 value = 7
Thread name: Thread-1 count2 value = 6
Thread name: Thread-1  count1 value = 8
Thread name: Thread-1 count2 value = 7
Thread name: Thread-1  count1 value = 9
Thread name: Thread-1 count2 value = 8
Thread name: Thread-1  count1 value = 10
Thread name: Thread-1 count2 value = 9
Thread name: Thread-1  count1 value = 11
Thread name: Thread-1 count2 value = 10
Thread name: Thread-1  count1 value = 12
Thread name: Thread-1 count2 value = 11
Thread name: Thread-1  count1 value = 13
Thread name: Thread-1 count2 value = 12
Thread name: Thread-1  count1 value = 14
Thread name: Thread-1 count2 value = 13
Thread name: Thread-1  count1 value = 15
Thread name: Thread-1 count2 value = 14
Thread name: Thread-1  count1 value = 16
Thread name: Thread-1 count2 value = 15
Thread name: Thread-1  count1 value = 17
Thread name: Thread-1 count2 value = 16
Thread name: Thread-1  count1 value = 18
Thread name: Thread-1 count2 value = 17
Thread name: Thread-1  count1 value = 19
Thread name: Thread-1 count2 value = 18
Thread name: Thread-1  count1 value = 20
Thread name: Thread-0 count2 value = 19
Thread name: Thread-0  count1 value = 21
Thread name: Thread-0 count2 value = 20
Thread name: Thread-0  count1 value = 22
Thread name: Thread-0 count2 value = 21
Thread name: Thread-0  count1 value = 23
Thread name: Thread-0 count2 value = 22
Thread name: Thread-0  count1 value = 24
Thread name: Thread-0 count2 value = 23
Thread name: Thread-0  count1 value = 25
Thread name: Thread-0 count2 value = 24
Thread name: Thread-0  count1 value = 26
Thread name: Thread-0 count2 value = 25
Thread name: Thread-0  count1 value = 27
Thread name: Thread-0 count2 value = 26
Thread name: Thread-0  count1 value = 28
Thread name: Thread-0 count2 value = 27
Thread name: Thread-0  count1 value = 29
Thread name: Thread-0 count2 value = 28
Thread name: Thread-0  count1 value = 30
Thread name: Thread-0 count2 value = 29
Thread name: Thread-0  count1 value = 31
Thread name: Thread-0 count2 value = 30
Thread name: Thread-0  count1 value = 32
Thread name: Thread-0 count2 value = 31
Thread name: Thread-0  count1 value = 33
Thread name: Thread-0 count2 value = 32
Thread name: Thread-0  count1 value = 34
Thread name: Thread-0 count2 value = 33
Thread name: Thread-0  count1 value = 35
Thread name: Thread-0 count2 value = 34
Thread name: Thread-0  count1 value = 36
Thread name: Thread-0 count2 value = 35
Thread name: Thread-0  count1 value = 37
Thread name: Thread-0 count2 value = 36
Thread name: Thread-0  count1 value = 38
Thread name: Thread-0 count2 value = 37
Thread name: Thread-0  count1 value = 39
Thread name: Thread-0 count2 value = 38
Thread name: Thread-0  count1 value = 40
Thread name: Thread-0 count2 value = 39
Thread name: Thread-0  count1 value = 41
Thread name: Thread-0 count2 value = 40
Thread name: Thread-0  count1 value = 42
Thread name: Thread-0 count2 value = 41
Thread name: Thread-0  count1 value = 43
Thread name: Thread-0 count2 value = 42
Thread name: Thread-0  count1 value = 44
Thread name: Thread-0 count2 value = 43
Thread name: Thread-0  count1 value = 45
Thread name: Thread-0 count2 value = 44
Thread name: Thread-0  count1 value = 46
Thread name: Thread-0 count2 value = 45
Thread name: Thread-0  count1 value = 47
Thread name: Thread-0 count2 value = 46
Thread name: Thread-0  count1 value = 48
Thread name: Thread-0 count2 value = 47
Thread name: Thread-0  count1 value = 49
Thread name: Thread-0 count2 value = 48
Thread name: Thread-0  count1 value = 50
Thread name: Thread-0 count2 value = 49
Thread name: Thread-0  count1 value = 51
Thread name: Thread-0 count2 value = 50
Thread name: Thread-0  count1 value = 52
Thread name: Thread-0 count2 value = 51
Thread name: Thread-0  count1 value = 53
Thread name: Thread-0 count2 value = 52
Thread name: Thread-0  count1 value = 54
Thread name: Thread-0 count2 value = 53
Thread name: Thread-0  count1 value = 55
Thread name: Thread-0 count2 value = 54
Thread name: Thread-0  count1 value = 56
Thread name: Thread-0 count2 value = 55
Thread name: Thread-0  count1 value = 57
Thread name: Thread-0 count2 value = 56
Thread name: Thread-0  count1 value = 58
Thread name: Thread-0 count2 value = 57
Thread name: Thread-0  count1 value = 59
Thread name: Thread-0 count2 value = 58
Thread name: Thread-0  count1 value = 60
Thread name: Thread-0 count2 value = 59
Thread name: Thread-0  count1 value = 61
Thread name: Thread-0 count2 value = 60
Thread name: Thread-0  count1 value = 62
Thread name: Thread-0 count2 value = 61
Thread name: Thread-0  count1 value = 63
Thread name: Thread-0 count2 value = 62
Thread name: Thread-0  count1 value = 64
Thread name: Thread-0 count2 value = 63
Thread name: Thread-0  count1 value = 65
Thread name: Thread-0 count2 value = 64
Thread name: Thread-0  count1 value = 66
Thread name: Thread-0 count2 value = 65
Thread name: Thread-0  count1 value = 67
Thread name: Thread-0 count2 value = 66
Thread name: Thread-0  count1 value = 68
Thread name: Thread-0 count2 value = 67
Thread name: Thread-0  count1 value = 69
Thread name: Thread-0 count2 value = 68
Thread name: Thread-0  count1 value = 70
Thread name: Thread-0 count2 value = 69
Thread name: Thread-0  count1 value = 71
Thread name: Thread-0 count2 value = 70
Thread name: Thread-0  count1 value = 72
Thread name: Thread-0 count2 value = 71
Thread name: Thread-0  count1 value = 73
Thread name: Thread-0 count2 value = 72
Thread name: Thread-0  count1 value = 74
Thread name: Thread-0 count2 value = 73
Thread name: Thread-0  count1 value = 75
Thread name: Thread-0 count2 value = 74
Thread name: Thread-0  count1 value = 76
Thread name: Thread-0 count2 value = 75
Thread name: Thread-0  count1 value = 77
Thread name: Thread-0 count2 value = 76
Thread name: Thread-0  count1 value = 78
Thread name: Thread-0 count2 value = 77
Thread name: Thread-0  count1 value = 79
Thread name: Thread-0 count2 value = 78
Thread name: Thread-0  count1 value = 80
Thread name: Thread-0 count2 value = 79
Thread name: Thread-0  count1 value = 81
Thread name: Thread-0 count2 value = 80
Thread name: Thread-0  count1 value = 82
Thread name: Thread-0 count2 value = 81
Thread name: Thread-0  count1 value = 83
Thread name: Thread-0 count2 value = 82
Thread name: Thread-0  count1 value = 84
Thread name: Thread-0 count2 value = 83
Thread name: Thread-0  count1 value = 85
Thread name: Thread-0 count2 value = 84
Thread name: Thread-0  count1 value = 86
Thread name: Thread-0 count2 value = 85
Thread name: Thread-0  count1 value = 87
Thread name: Thread-0 count2 value = 86
Thread name: Thread-0  count1 value = 88
Thread name: Thread-0 count2 value = 87
Thread name: Thread-0  count1 value = 89
Thread name: Thread-0 count2 value = 88
Thread name: Thread-0  count1 value = 90
Thread name: Thread-0 count2 value = 89
Thread name: Thread-0  count1 value = 91
Thread name: Thread-0 count2 value = 90
Thread name: Thread-0  count1 value = 92
Thread name: Thread-0 count2 value = 91
Thread name: Thread-0  count1 value = 93
Thread name: Thread-0 count2 value = 92
Thread name: Thread-0  count1 value = 94
Thread name: Thread-0 count2 value = 93
Thread name: Thread-0  count1 value = 95
Thread name: Thread-0 count2 value = 94
Thread name: Thread-0  count1 value = 96
Thread name: Thread-0 count2 value = 95
Thread name: Thread-0  count1 value = 97
Thread name: Thread-0 count2 value = 96
Thread name: Thread-0  count1 value = 98
Thread name: Thread-0 count2 value = 97
Thread name: Thread-0  count1 value = 99
Thread name: Thread-0 count2 value = 98
Thread name: Thread-0  count1 value = 100
Thread name: Thread-0 count2 value = 99
Thread name: Thread-0  count1 value = 101
Thread name: Thread-0 count2 value = 100
Thread name: Thread-0  count1 value = 102
Thread name: Thread-0 count2 value = 101
Thread name: Thread-0  count1 value = 103
Thread name: Thread-0 count2 value = 102
Thread name: Thread-0  count1 value = 104
Thread name: Thread-0 count2 value = 103
Thread name: Thread-0  count1 value = 105
Thread name: Thread-0 count2 value = 104
Thread name: Thread-0  count1 value = 106
Thread name: Thread-0 count2 value = 105
Thread name: Thread-0  count1 value = 107
Thread name: Thread-0 count2 value = 106
Thread name: Thread-0  count1 value = 108
Thread name: Thread-0 count2 value = 107
Thread name: Thread-0  count1 value = 109
Thread name: Thread-0 count2 value = 108
Thread name: Thread-0  count1 value = 110
Thread name: Thread-0 count2 value = 109
Thread name: Thread-0  count1 value = 111
Thread name: Thread-0 count2 value = 110
Thread name: Thread-0  count1 value = 112
Thread name: Thread-0 count2 value = 111
Thread name: Thread-0  count1 value = 113
Thread name: Thread-0 count2 value = 112
Thread name: Thread-0  count1 value = 114
Thread name: Thread-0 count2 value = 113
Thread name: Thread-0  count1 value = 115
Thread name: Thread-0 count2 value = 114
Thread name: Thread-0  count1 value = 116
Thread name: Thread-0 count2 value = 115
Thread name: Thread-0  count1 value = 117
Thread name: Thread-0 count2 value = 116
Thread name: Thread-0  count1 value = 118
Thread name: Thread-0 count2 value = 117
Thread name: Thread-0  count1 value = 119
Thread name: Thread-0 count2 value = 118
Thread name: Thread-1 count2 value = 119
Thread name: Thread-1  count1 value = 120
Thread name: Thread-1 count2 value = 120
Thread name: Thread-1  count1 value = 121
Thread name: Thread-1 count2 value = 121
Thread name: Thread-1  count1 value = 122
Thread name: Thread-1 count2 value = 122
Thread name: Thread-1  count1 value = 123
Thread name: Thread-1 count2 value = 123
Thread name: Thread-1  count1 value = 124
Thread name: Thread-1 count2 value = 124
Thread name: Thread-1  count1 value = 125
Thread name: Thread-1 count2 value = 125
Thread name: Thread-1  count1 value = 126
Thread name: Thread-1 count2 value = 126
Thread name: Thread-1  count1 value = 127
Thread name: Thread-1 count2 value = 127
Thread name: Thread-1  count1 value = 128
Thread name: Thread-1 count2 value = 128
Thread name: Thread-1  count1 value = 129
Thread name: Thread-1 count2 value = 129
Thread name: Thread-1  count1 value = 130
Thread name: Thread-1 count2 value = 130
Thread name: Thread-1  count1 value = 131
Thread name: Thread-1 count2 value = 131
Thread name: Thread-1  count1 value = 132
Thread name: Thread-1 count2 value = 132
Thread name: Thread-1  count1 value = 133
Thread name: Thread-1 count2 value = 133
Thread name: Thread-1  count1 value = 134
Thread name: Thread-1 count2 value = 134
Thread name: Thread-1  count1 value = 135
Thread name: Thread-1 count2 value = 135
Thread name: Thread-1  count1 value = 136
Thread name: Thread-1 count2 value = 136
Thread name: Thread-1  count1 value = 137
Thread name: Thread-1 count2 value = 137
Thread name: Thread-1  count1 value = 138
Thread name: Thread-1 count2 value = 138
Thread name: Thread-1  count1 value = 139
Thread name: Thread-1 count2 value = 139
Thread name: Thread-1  count1 value = 140
Thread name: Thread-1 count2 value = 140
Thread name: Thread-1  count1 value = 141
Thread name: Thread-1 count2 value = 141
Thread name: Thread-1  count1 value = 142
Thread name: Thread-1 count2 value = 142
Thread name: Thread-1  count1 value = 143
Thread name: Thread-1 count2 value = 143
Thread name: Thread-1  count1 value = 144
Thread name: Thread-1 count2 value = 144
Thread name: Thread-1  count1 value = 145
Thread name: Thread-1 count2 value = 145
Thread name: Thread-1  count1 value = 146
Thread name: Thread-1 count2 value = 146
Thread name: Thread-1  count1 value = 147
Thread name: Thread-1 count2 value = 147
Thread name: Thread-1  count1 value = 148
Thread name: Thread-1 count2 value = 148
Thread name: Thread-1  count1 value = 149
Thread name: Thread-1 count2 value = 149
Thread name: Thread-1  count1 value = 150
Thread name: Thread-1 count2 value = 150
Thread name: Thread-1  count1 value = 151
Thread name: Thread-1 count2 value = 151
Thread name: Thread-1  count1 value = 152
Thread name: Thread-1 count2 value = 152
Thread name: Thread-1  count1 value = 153
Thread name: Thread-1 count2 value = 153
Thread name: Thread-1  count1 value = 154
Thread name: Thread-1 count2 value = 154
Thread name: Thread-1  count1 value = 155
Thread name: Thread-1 count2 value = 155
Thread name: Thread-1  count1 value = 156
Thread name: Thread-1 count2 value = 156
Thread name: Thread-1  count1 value = 157
Thread name: Thread-1 count2 value = 157
Thread name: Thread-1  count1 value = 158
Thread name: Thread-1 count2 value = 158
Thread name: Thread-1  count1 value = 159
Thread name: Thread-1 count2 value = 159
Thread name: Thread-1  count1 value = 160
Thread name: Thread-1 count2 value = 160
Thread name: Thread-1  count1 value = 161
Thread name: Thread-1 count2 value = 161
Thread name: Thread-1  count1 value = 162
Thread name: Thread-1 count2 value = 162
Thread name: Thread-1  count1 value = 163
Thread name: Thread-1 count2 value = 163
Thread name: Thread-1  count1 value = 164
Thread name: Thread-1 count2 value = 164
Thread name: Thread-1  count1 value = 165
Thread name: Thread-1 count2 value = 165
Thread name: Thread-1  count1 value = 166
Thread name: Thread-1 count2 value = 166
Thread name: Thread-1  count1 value = 167
Thread name: Thread-1 count2 value = 167
Thread name: Thread-1  count1 value = 168
Thread name: Thread-1 count2 value = 168
Thread name: Thread-1  count1 value = 169
Thread name: Thread-1 count2 value = 169
Thread name: Thread-1  count1 value = 170
Thread name: Thread-1 count2 value = 170
Thread name: Thread-1  count1 value = 171
Thread name: Thread-1 count2 value = 171
Thread name: Thread-1  count1 value = 172
Thread name: Thread-1 count2 value = 172
Thread name: Thread-1  count1 value = 173
Thread name: Thread-1 count2 value = 173
Thread name: Thread-1  count1 value = 174
Thread name: Thread-1 count2 value = 174
Thread name: Thread-1  count1 value = 175
Thread name: Thread-1 count2 value = 175
Thread name: Thread-1  count1 value = 176
Thread name: Thread-1 count2 value = 176
Thread name: Thread-1  count1 value = 177
Thread name: Thread-1 count2 value = 177
Thread name: Thread-1  count1 value = 178
Thread name: Thread-1 count2 value = 178
Thread name: Thread-1  count1 value = 179
Thread name: Thread-1 count2 value = 179
Thread name: Thread-1  count1 value = 180
Thread name: Thread-1 count2 value = 180
Thread name: Thread-1  count1 value = 181
Thread name: Thread-1 count2 value = 181
Thread name: Thread-1  count1 value = 182
Thread name: Thread-1 count2 value = 182
Thread name: Thread-1  count1 value = 183
Thread name: Thread-1 count2 value = 183
Thread name: Thread-1  count1 value = 184
Thread name: Thread-1 count2 value = 184
Thread name: Thread-1  count1 value = 185
Thread name: Thread-1 count2 value = 185
Thread name: Thread-1  count1 value = 186
Thread name: Thread-1 count2 value = 186
Thread name: Thread-1  count1 value = 187
Thread name: Thread-1 count2 value = 187
Thread name: Thread-1  count1 value = 188
Thread name: Thread-1 count2 value = 188
Thread name: Thread-1  count1 value = 189
Thread name: Thread-1 count2 value = 189
Thread name: Thread-1  count1 value = 190
Thread name: Thread-1 count2 value = 190
Thread name: Thread-1  count1 value = 191
Thread name: Thread-1 count2 value = 191
Thread name: Thread-1  count1 value = 192
Thread name: Thread-1 count2 value = 192
Thread name: Thread-1  count1 value = 193
Thread name: Thread-1 count2 value = 193
Thread name: Thread-1  count1 value = 194
Thread name: Thread-1 count2 value = 194
Thread name: Thread-1  count1 value = 195
Thread name: Thread-1 count2 value = 195
Thread name: Thread-1  count1 value = 196
Thread name: Thread-1 count2 value = 196
Thread name: Thread-1  count1 value = 197
Thread name: Thread-1 count2 value = 197
Thread name: Thread-1  count1 value = 198
Thread name: Thread-1 count2 value = 198
Thread name: Thread-1  count1 value = 199
Thread name: Thread-1 count2 value = 199
Thread name: Thread-1  count1 value = 200
Thread name: Thread-1 count2 value = 200
Count1=200  Count2=200

因此,当线程确实获得访问权限时,它会同时拥有两个synchronized 方法。当控制从一个线程切换到另一线程时,计数器值会更新并被记住。

最佳答案

将会发生的情况是,两个线程都调用 compute() 方法,进入 for 循环,并在第一次调用 add() 时结束。

两者之一将先于另一个到达,因此他将进入 synchronized 方法。当他在该方法中时,第二个线程可能会到达 add() 调用。这是一个可能,因为你无法说出哪个线程在哪个时间点位于哪个位置。 JVM 决定哪些线程可以在什么时间执行操作是未定义的。但我们假设第二个线程到达 add() 调用并且现在想要执行该方法。它不能这样做,因为它是同步并且另一个线程当前已经在调用它。所以线程进入等待状态。第一个线程完成对 add() 的调用。现在,第二个线程可能会进入 add(),执行调用,退出 add() 并进入 addAgain() 。现在,第一个线程正在等待。

这可能听起来令人困惑,而这正是我想要达到的目的:

你无法说出哪个线程何时调用哪个方法。 JVM 可能决定让第一个线程首先执行这两个方法的 100 次调用,然后第二个线程执行相同的操作。它可能会决定他们称它们为交替。现实情况可能介于两者之间。在另一个线程完成初始化之前,两个线程之一甚至可能不会进入compute()方法。你说不出来。这一切都取决于您的系统、处理器的数量、发生的代码和 CPU 优化、正在使用的算法调度程序等等。

一旦你进行了多线程处理,发生什么事情就脱离了你的掌控。通过调用join,您可以等待任务完成。但没有确定的方法可以保证在 1 毫秒、2 毫秒或 250 毫秒内会出现这种情况。

<小时/>

所以你的问题:

  1. When a thread calls the compute method, does it get access to both of the synchronized methods inside and execute the increment operation?

不,没有。通过调用add,它可以访问此方法。它不会自动访问第二种方法。

  1. If a thread gets access to the for loop, does it complete the for loop or leave it before the competition to share with the other thread?

你不能说。它既不保证完成循环,也不保证在完成之前被中断。

  1. If its the case, I assume the other thread is in the wait phase and don't do much. Is this correct?

如果线程尝试访问已被另一个线程访问的同步方法,则该线程将处于等待状态。

关于java - 多线程中的同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49316209/

相关文章:

java - 如何使用 Java 设置 Selenium WebDriver?

java - 解析文本的最快/最简单的方法

java - 并发读者-作者的行为方式出乎意料

c# - 不能使用与其父 Freezable 属于不同线程的 DependencyObject - prism

java - 单击数字键盘上的 "Done"按钮时应用程序崩溃

javascript - AngularJs POST 方法到 springboot api

java - Gradle不运行测试

multithreading - Ocaml:有没有办法在进程之间传递对象?

swift - 究竟如何在后台线程上渲染 Metal?

c++ - GCC 8.1.0/MinGW64 编译的 OpenMP 程序崩溃寻找 cygwin.s?