先读取再设值:
new Thread(() -> {
int loop = 0;
while (run) {
loop++;
}
System.out.println("loop=" + loop);
}).start();
new Thread(()->{
sleep(1000);//先暂停1s确保先读取
run = false;
sleep(2000);
}).start();
测试结果:一直循环
先设值再读取:
new Thread(() -> {
int loop = 0;
sleep(1000);//先暂停1s确保先设值
while (run) {
loop++;
}
System.out.println("loop=" + loop);
}).start();
new Thread(()->{
run = false;
sleep(2000);
}).start();
测试结果:总是输出loop=0,说明根本没进循环,并且线程1先退出,过大概2s后线程2退出。
在测试1的基础上在循环中加入sleep(1):
new Thread(() -> {
int loop = 0;
while (run) {
loop++;
sleep(1);//在循环中让cpu执行1ms
}
System.out.println("loop=" + loop);
}).start();
new Thread(()->{
sleep(1000);//先暂停1s确保先读取
run = false;
sleep(2000);
}).start();
测试结果:输出loop=987,loop的次数在950-1050之间,说明在thread2的sleep(1000)之后thread1马上就读取到了最新值,而不是thread2线程结束后。如果sleep(2000),则总是输出loop=1,说明sleep方法结束后立马读取到正确的run值。
注意: 如果sleep函数里面的循环次数变少,还是不能退出循环。本机测试如果sleep函数中的循环次数小于29000次,则还是会一直循环下去,只要超过30000次,总是能退出循环。
在测试3的基础上,把sleep(1)替换为实际的for循环:
new Thread(() -> {
int loop = 0;
while (run) {
loop++;
//停顿1ms
for (long i = 0; i < 3000000L * 1; i++) {}
}
System.out.println("loop=" + loop);
}).start();
new Thread(()->{
sleep(1000);//先暂停1s确保先读取
run = false;
sleep(2000);
}).start();
测试结果:一直循环。不管 i 是多少都会一直循环。
在测试1的基础上加入synchronized语句:
new Thread(() -> {
int loop = 0;
while (run) {
loop++;
synchronized (Object.class){}
}
System.out.println("loop=" + loop);
}).start();
new Thread(()->{
sleep(1000);//先暂停1s确保先读取
run = false;
sleep(2000);
}).start();
测试结果:loop=45830307,能结束循环,loop次数没有意义。
在测试1的基础上加入lock.lock()语句:
new Thread(() -> {
int loop = 0;
while (run) {
loop++;
lock.lock(); //static Lock lock = new ReentrantLock();
}
System.out.println("loop=" + loop);
}).start();
new Thread(()->{
sleep(1000);//先暂停1s确保先读取
run = false;
sleep(2000);
}).start();
测试结果:loop=55020323,能正常退出循环。