我将你这部分代码放到 IDEA 里面,用 JAVC 编译。 发现 for 循环是这样的。
编译前:
for (int i = 0; i < 5; ) {
lock.lock();
if (sign % 3 == 0){
System.out.print("a");
sign++;
i++;
}
lock.unlock();
}
编译后:
for (int i = 0; i < 5; lock.unlock();) {
for(语句 A; 语句 B; 语句 C){
语句 A 在整个循环过程中,只会执行一次;语句 B 必须是布尔类型的表达式(当然也可以不写,如果写就必须是布尔类型表达式),通过该布尔表达式去判断是否继续执行循环体;语句 C 会在每次循环结束后执行,也就是说,循环体执行多少次,语句 C 就会执行多少次。(抄自
https://www.jb51.net/article/157807.htm )
根据编译后+jb 网站的猜测。当 A 线程获取到锁之后。B 线程如果需要再获取锁,肯定是需要 A 线程释放锁,B 才有机会的。
但是我的问题是:
1.不管语句 C 是什么情况: 只要有语句 B 返回的是布尔值。 第一次肯定会触发一次循环体的。 那么为什么不管怎么样都是先打印 a 而不是先打印 b or c
2.后续我将 for 循环改成普通的模式 for (int i = 0; i < 5; i++) {
lock 变量改为 static volatile ReentrantLock lock = new ReentrantLock();
sign 改为 static volatile AtomicInteger sign = new AtomicInteger(0);
发现只会打印一次 abc 但是依然无法理解为什么一定是打印 abc 不是 acb cba 等