Home  >  Article  >  Java  >  Example analysis of visibility problem of Java variables

Example analysis of visibility problem of Java variables

王林
王林forward
2023-05-01 22:28:091516browse

Question: Can synchorized and sleep also achieve the purpose of volatile thread visibility? The general problem description is as follows:

package com.test;

import java.util.concurrent.TimeUnit;

public class test1 {

private static boolean is = true;

public static void main(String[] args) {

new Thread(new Runnable() {

@Override

public void run() {

int i = 0;

while(test1.is){

i ;

1 //synchronized (this) { } will forcefully refresh the variable value of the main memory to the thread stack?

2 //System.out.println("1"); println is synchronized and will force the variable value of the main memory to be refreshed to the thread stack?

3 //sleep will reload the value of the main memory?

// try {

// TimeUnit.MICROSECONDS.sleep(1);

// }catch (InterruptedException e) {

// e.printStackTrace();

// }

}

}

}).start();

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

new Thread(new Runnable() {

@Override

public void run() {

is = false; //Set is to false so that the above thread ends the while loop

}

}).start();

}

}

Q: Why doesn't the entire program terminate? Why does the program terminate when you uncomment any of the code blocks (1, 2, 3)? Will synchronized forcefully refresh the memory variable values ​​​​to the thread stack? What will sleep do?

Involving knowledge explanation

volatile: This keyword ensures the visibility of variables in threads. All threads accessing variables modified by volatile must read from the main memory before operating, and write back to the main memory immediately after the working memory is modified, ensuring that other threads Visibility, the keyword with the same effect is final.

synchronized: All synchronization operations must ensure 1. Atomicity and 2. Visibility, so changes that occur in the synchronized block will be immediately written back to the main memory

sleep: This method will only give up CPU execution time and will not release the lock.

problem analysis

Q1: Why does the program not terminate after commenting the code?

A1: Because the variable value of boolean is=true is loaded into its own working memory by the previous thread (referred to as thread A), after the subsequent thread (referred to as thread B) changes boolean is=false, it may not be written to the main memory immediately (but In this question, it should be written to the main memory immediately, because the thread will exit after executing is=false). Even if it is written to the main memory immediately, thread A may not be loaded into the working memory immediately, so the program continues Won't it terminate? This is what most of us think of, but in fact, the JVM has been optimized to a large extent for the current hardware level, basically ensuring the timely synchronization of working memory and main memory to a large extent, which is equivalent to using volatile by default. But only to the maximum extent! When CPU resources are always occupied, the synchronization between the working memory and the main memory, that is, the visibility of variables will not be so timely! The conclusion will be verified later.

Q2: Why does the program terminate when you uncomment any code block (1, 2, 3)?

A2: The codes with line numbers 1 and 2 have a common feature, that is, they all involve synchronized synchronization locks. So, as the question author guessed, will synchronized forcefully refresh the variable values ​​​​in the main memory to the thread stack? , and the sleep method will also refresh the variable values ​​​​in the main memory to the thread stack? In fact, we said earlier that synchronized will only ensure the visibility of variables in the synchronized block, and the is variable is not in the synchronized block, so it is obviously not caused by this. Next we add the following code after code i;:

for(int k=0;k<100000;k ){

new Object();

}

If you run it again, the program will terminate immediately! Why? In A1 above, we have said that even with JVM optimization, when the CPU is always occupied, the visibility of the data cannot be well guaranteed, just like the above program keeps looping to do i; the operation occupies the CPU. And why does the program stop after adding the above code? Because for a large number of new Object() operations, the CPU is no longer the main time-consuming operation. The real time-consuming should be in the allocation of memory (because the processing speed of the CPU is obviously faster than the memory, otherwise there would be no CPU registers. ), so after the CPU is idle, it will follow the JVM optimization benchmark to ensure the visibility of data as quickly as possible, thereby synchronizing the is variable from the main memory to the working memory, eventually leading to the end of the program. This is why the sleep() method does not involve synchronization operations. , but the program can still be terminated, because the sleep() method will release the CPU but not the lock!

The above is the detailed content of Example analysis of visibility problem of Java variables. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete