volatile 作用
例如线程A依赖 boolean b 作为退出条件. 但是b的值在线程B中改变的.
如果线程B更改了值,线程A并不知道线程B更改了主内存的值还是会继续运行,我们加上volatile关键字后线程A会每次从主内存中取值,线程B更改后会线程A会及时发现并及时作出处理
代码示例
package cn.wyj.learn.juc;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 线程间通信
*/
@Slf4j
public class VolatileExample1 {
static boolean b = true;
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
while (b) {
}
log.info("线程A结束,结束时间{}", DateFormatUtils.format(new Date(), "hh:mm:ss:SSS"));
});
executorService.execute(() -> {
try {
log.info("线程B在做业务");
TimeUnit.SECONDS.sleep(2);
b = false;
log.info("线程B程结束,结束时间{}", DateFormatUtils.format(new Date(), "hh:mm:ss:SSS"));
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executorService.shutdown();
//等待10s退出
executorService.awaitTermination(10, TimeUnit.SECONDS);
log.info("程序结束,结束时间{}", DateFormatUtils.format(new Date(), "hh:mm:ss:SSS"));
}
}
运行结果
20:55:14.432 [pool-1-thread-2] INFO cn.wyj.learn.juc.VolatileExample1 - 线程B在做业务
20:55:16.523 [pool-1-thread-2] INFO cn.wyj.learn.juc.VolatileExample1 - 线程B程结束,结束时间08:55:16:437
20:55:24.430 [main] INFO cn.wyj.learn.juc.VolatileExample1 - 程序结束,结束时间08:55:24:430
static volatile boolean b = true;
20:58:07.097 [pool-1-thread-2] INFO cn.wyj.learn.juc.VolatileExample1 - 线程B在做业务
20:58:09.204 [pool-1-thread-2] INFO cn.wyj.learn.juc.VolatileExample1 - 线程B程结束,结束时间08:58:09:105
20:58:09.204 [pool-1-thread-1] INFO cn.wyj.learn.juc.VolatileExample1 - 线程A结束,结束时间08:58:09:105
20:58:09.207 [main] INFO cn.wyj.learn.juc.VolatileExample1 - 程序结束,结束时间08:58:09:207