The purpose of life is to grow, the essence of life is to change, the challenge of life is to conquer
The purpose of life is to grow, the essence of life is to change, the challenge of life is to conquer
Today, let’s talk about the use of synchronized and how it is used
As we all know, there are three major features in the Java memory model: atomicity, visibility, and orderliness
Synchronized: ensures visibility and atomicity
In the Java memory model, synchronized specifies that when a thread locks, it first emptying the working memory –> copying the latest variable into the main memory –> executing the code –> flushing the value of the changed shared variable into the main memory –> releasing the mutex
Orderliness: The natural orderliness of Java programs can be summed up in a sentence: if you observe in one thread, all operations are naturally ordered, and if you observe in one thread, all operations are out of order
See the following uses the double check lock singleton mode
private volatile static Singleton singleton;
public static Singleton getSingleton() {if(null == singleton){
synchronized (Singleton.class) {
if(null == singleton){ singleton = new Singleton(); }}}return singleton;
}
public static void main(String[] args) {
for(int i = 0; i<10; i++){ new Thread(newRunnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+Singleton.getSingleton().hashCode());
}}).start();
}Copy the code
As you can see, the Singleton object is volatile and nulled twice. Volatile is used to make the variable change visible (volatile is also a keyword). The second nulling is because the first nulling is Singleton and only one instance needs to be created. The previously created instance is returned directly, so you do not need to execute the code in the synchronous method most of the time, greatly improving performance. The second sentence is empty after executing thread 1 check for the first time that the CPU thread 2 has been executive power, the next thread 2 lock, create an instance Thread 1 at this moment, get the executive power, also create an instance, the results will lead to create multiple instances, so need a second check inside the synchronized code, if the instance is empty, is to create, This ensures that only one object is created
Synchronized can be added to methods as well as code blocks
class Sync{
public synchronized void test() {
System.out.println("The test start..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The test end..");
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for(int i = 0; i < 3; i++) { Thread thread = new MyThread(); thread.start(); }}}}Copy the code
Running results:
Didn’t change, didn’t see synchronized in action
Let’s try adding synchronized to the block to reduce the granularity of the lock
class Sync {
public void test(a) {
synchronized (Sync.class) {
System.out.println("The test start..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The test end.."); }}}class MyThread extends Thread {
public void run(a) {
Sync sync = newSync(); sync.test(); }}public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = newMyThread(); thread.start(); }}}Copy the code
Running results:testStart..testThe end..testStart..testThe end..testStart..testThe end..Copy the code
Synchronized locks not this, but the Class object of the synchronized Class
Reentrancy of Synchronized
conclusion
Synchronized locks either instances of that class or objects that are passed in. Again, synchronized makes variables or blocks of code accessible only to one thread at a time