简单描述下代码:
static 变量 i
线程 1:尝试把 i 设为 1
线程 2:尝试把 i 设为 2 ,如果 i 为 1 ,print i
不断运行线程 1 和 2
public class Main {
// static 变量 i
static volatile Integer i = 0;
public static void main(String[] args) throws Exception {
// 线程 1
Thread thread1 = new Thread(()->{
synchronized(i) {
try {
i = 1;
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
// 线程 2
Thread thread2 = new Thread(()->{
synchronized (i) {
try {
i = 2;
Thread.sleep(100);
if (i == 1) {
System.out.println("1"); // 实际运行结果为 1
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
// 不断运行线程 1 和 2
while (true) {
new Thread(thread1).start();
new Thread(thread2).start();
}
}
}
为什么运行的结果是 1
还请各位大佬不吝赐教(抱拳),
谢谢各位大哥
1
RedBeanIce 2023-02-02 19:29:07 +08:00
import java.util.concurrent.atomic.AtomicLong;
public class VolatileTest1 { private static final AtomicLong THREAD1_COUNT = new AtomicLong(0); private static final AtomicLong THREAD2_COUNT = new AtomicLong(0); // static 变量 i static volatile Integer i = 0; public static void main(String[] args) throws Exception { // 线程 1 Thread thread1 = new Thread(() -> { synchronized (i) { try { i = 1; Thread.sleep(100); THREAD1_COUNT.incrementAndGet(); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); // 线程 2 Thread thread2 = new Thread(() -> { synchronized (i) { try { i = 2; Thread.sleep(100); if (i == 1) { System.out.println("1"); // 实际运行结果为 1 System.out.println("thread1 运行次数" + THREAD1_COUNT.get()); System.out.println("thread2 运行次数" + THREAD2_COUNT.get()); } THREAD2_COUNT.incrementAndGet(); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); // 不断运行线程 1 和 2 while (true) { new Thread(thread1).start(); new Thread(thread2).start(); } } } 要不你试试这个,,看看 |
2
kkkbbb 2023-02-02 19:30:58 +08:00
只有等于 1 才打印啊
|
3
hefish 2023-02-02 19:32:05 +08:00
按我的理解,sleep 了啊,然后把时间片给别人了啊,然后别人设了个 1 ,然后别人 sleep ,然后轮到你检测 i 了。
|
4
Nooooobycat 2023-02-02 19:39:57 +08:00
你线程 2 把 Integer 的值改掉之后,值为 1 的 Integer 对象锁还是在线程 2 上,线程 1 此时也可以进入 synchronized 代码块(获取到的是值为 2 的 Integer 对象的锁,然后又改回 1 。然后紧接着线程 2 就执行到了 if 语句并输出了
|
5
Jooooooooo 2023-02-02 19:41:57 +08:00
你用一个对象装着 i, 然后锁那个对象.
|