Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities
Code shrimp is a sand carving and funny boy who likes listening to music, playing games and writing as well as most of his friends. The days are still very long, let’s refuel our efforts together 🌈
✨ role
Taking the double-checked singleton pattern as an example, start with the code
public class Singleton {
public Singleton(a) {}private static volatile Singleton singleton;
public static Singleton getSingleton(a) {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = newSingleton(); }}}returnsingleton; }}Copy the code
As the code above shows, The Singleton uses the volatile modifier, and we all know what volatile does
- Atomicity is not guaranteed
- Ensure visibility of shared variables
- Disallow instruction reordering
So what exactly does volatile do in singleton mode?
In fact, in singleton mode, volatile is primarily used to prohibit instruction reordering
So why?
In the above code, singleton = new Singleton(); It can be decomposed into the following steps:
- Allocates object memory space
- Initialize an object
- Set the Singleton to the allocated memory address
But step 2,3 can be swapped, that is, reordering, but according to the Java language specification intra-thread semantics, it allows reordering that does not change the execution result of a single-threaded program in a single thread. In other words, if step 2,3 is reordered, for a single thread, The first time you access an object, the result is always correct, so it doesn’t matter if you reorder it.
However, in a multi-threaded environment, this can be problematic, for example, in the following reordering case:
time | Thread A | Thread B |
---|---|---|
t1 | Allocating object space | |
t2 | Set singleton to point to allocated memory space | |
t3 | Check whether the singleton is empty | |
t4 | Since the Singleton is not NULL, thread B will access the object referenced by the Singleton | |
t5 | Initialize an object | |
t6 | Access the object referenced by the Singleton |
In normal flow, thread A should initialize the Singleton at t2 time, and thread B at t2 time
You might have a friend who’s just about to kick in, so I’ll say it again according to the code
public class Singleton {
public Singleton(a) {}private static volatile Singleton singleton;
public static Singleton getSingleton(a) {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = newSingleton(); }}}returnsingleton; }}Copy the code
According to the code, if thread A is at line 12 then singleton = new Singleton(); If (singleton == null) on line 9, thread B may determine that the singleton is not null, and then take the returned singleton to do something else, resulting in an error.
At this point, I believe that you almost understand, if you do not understand, you can read it twice.
So to address this problem, we used volatile to modify the Singleton to prevent possible problems with reordering.
😉 Featured column
Self-introduction, to everyone recommend their column 😁, welcome small partners to collect attention 😊
The small white to learn Java
MybatisPlus column
App crawler Column
PC side crawler column
Big factory interview question column
❤ finally
I am aCode pipi shrimp, a prawns lover who loves to share knowledge, will update useful blog posts in the future, looking forward to your attention!!
Creation is not easy, if this blog is helpful to you, I hope you can == one key three even oh! Thank you for your support. See you next time