Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the reason for the emergence of Bug in Java concurrent programs

2025-04-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "what is the reason for Bug in Java concurrent programs?" in the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Visibility issu

Visibility means that one thread makes changes to the shared variable, and other threads can see the updated value of the shared variable immediately, which seems to be a reasonable requirement, but in the case of multithreading, you may be disappointed. Since each CPU has its own cache, each thread may use a different CPU, which will cause the problem of data visibility. Take a look at the following figure:

The relationship between CUP cache and main memory

For a shared variable count, there is a copy of count in each CPU cache. Each thread can only operate its own copy in the CPU cache for the operation of the shared variable count, but cannot directly manipulate the copy in the main memory or other CPU cache, which leads to data differences. A typical example of a program problem caused by visibility in a multithreaded case is the accumulation of variables, such as the following program:

Public class Demo {private int count = 0; / / each thread is count + 10000 public void add () {for (int I = 0; I)

< 10000; i++) { count += 1; } } public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 10; i++) { Demo demo = new Demo(); Thread t1 = new Thread(() ->

{demo.add ();}); Thread T2 = new Thread (()-> {demo.add ();}); t1.start (); t2.start (); t1.join (); t2.join (); System.out.println (demo.count) }

We used two programs to accumulate count variables, each thread accumulating 10000 times, the final result should be 20000 times, but after you execute many times, you will find that the result is not necessarily 20000 times, this is due to the visibility of shared variables.

We started two threads T1 and T2. When the thread starts, it reads the count of the current main memory into its own CPU cache. At this time, the value of count may be 0 or 1 or something else. We default to 0, and each thread will perform the operation count + = 1, which is a parallel operation. The count in CPU1 and CPU2 cache is 1, and then they write the count in their cache back to main memory. At this time, the count in the main memory is also 1, which is not the 2 we expected. This is the result of data visibility.

Atomicity problem

Atomicity: that is, one or more operations, either all and the process of execution will not be interrupted by any factor, or none of them will be performed. This atomicity is aimed at the CPU level, not the atomicity in our Java code. Take the count + = 1 command in our visibility Demo program as an example, this Java command will eventually be compiled into the following three CPU instructions:

Load the variable count from memory into the register of CPU, assuming count = 1

Perform the count + 1 operation in the register, count = 1: 1 = 2

Write the count after + 1 to memory

This is a typical read-change-write operation, but it is not atomic, because there is competition between multicore CPU, not a certain CPU always executes, they will constantly preempt execution power and release execution power, so the above three instructions are not necessarily atomic. The following figure shows the simulation flow of two thread count + = 1 commands:

Non-atomic operation

After the CPU of thread 1 finished executing the first two instructions, the execution right was preempted by the CPU of thread 2. At this time, the CPU execution of thread 1 was suspended and waited for the execution power to be obtained again. After the CPU of thread 2 obtained the execution power, it first read the count from memory. At this time, the count in memory is still 1, and the CPU where thread 2 is located happens to have executed the three instructions. After thread 2 has finished execution, the count in memory is equal to 2. At this time, thread 1 gets the right to execute again, and thread 1 only has the last command to write count back to memory. After execution, the value of count in memory is still 2, not the 3 we expected.

Order problem

Orderliness: the order in which the program is executed is in the order of the code, such as the following code

1 int I = 1; 2 int m = 11; 3 long x = 23L

If it is ordered, it needs to be executed in the order of the code, but the execution result is not necessarily in this order, because in order to improve the running efficiency of the program, JVM will execute the above code in the order considered by the JVM compiler to be better, which may disrupt the execution order of the code, because it will ensure that the final execution result of the program is consistent with that of the code sequence. This is what we call instruction reordering.

A typical case of program Bug due to instruction reordering is the singleton mode of double detection lock without the volatile keyword, as shown in the following code:

Public class Singleton {static Singleton instance Public static Singleton getInstance () {/ / determines if (instance = = null) {/ / lock for the first time, and only one thread can acquire the lock synchronized (Singleton.class) {/ / determine if (instance = = null) / / build the object for the second time There is a lot of knowledge here. Instance = new Singleton () }} return instance;}}

The double detection lock scheme looks perfect, but in the actual run, there will be Bug, there will be the problem of object escape, and you may get an unbuilt Singleton object, which is the problem of instruction reordering when building Singleton objects. Let's first take a look at the instructions for building the ideal type of object:

Instruction 1: allocate a piece of memory M

Instruction 2: initialize the Singleton object on memory M

Instruction 3: then the address of M is assigned to the instance variable.

However, this may not be the case on the JVM compiler and may be optimized to the following instructions:

Instruction 1: allocate a piece of memory M

Instruction 2: assign the address of M to the instance variable

Instruction 3: finally initialize the Singleton object on memory M.

It seems that a small optimization, that is, such a small optimization, will make your program unsafe. Suppose that after the thread that grabbed the lock has executed instruction 2, the instance is no longer empty. Thread C comes. Thread C sees that the instance is not empty and will directly return the instance object. At this time, the instance has not been initialized successfully. A null pointer exception may be triggered when a method or member variable of an instance object is called. Possible execution flowchart:

Singleton mode of double detection lock without volatile keyword

The above are the three reasons that cause Java programs to produce Bug in the case of multithreading. JDK also gives corresponding solutions to these problems, as shown in the figure below. More details of these solutions will be described in detail later.

This is the end of the content of "what is the reason for Bug in Java concurrent programs?" Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report