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 atomic class of the advanced concurrent programming series

2025-01-18 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 atomic class of advanced concurrent programming series". 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!

1. Test you

I believe that as a senior programmer, you will not be unfamiliar with classes like AtomicInteger, that is, classes that start with Atomic. When we look at a lot of framework source code, or third-party components, we will often see them, like a shadow.

So the question is, what exactly does a class like Atomicxxx mean? It is easier to understand from the literal meaning, Atomic is atomicity, then Atomicxxx is atomic class. At this point, you must remember that we talked about the three basic elements of thread safety. Let's review them together: visibility, atomicity, and orderliness. The atomicity of atomic class is about this atomicity, so you can first remember a conclusion: atomic class, it is a thread-safe class.

Some friends here may question: when you say thread safety, do you mean thread safety? I'm not convinced. You didn't make it clear. I won't listen, I won't listen. All right, don't be in a hurry, just listen to me analyze and talk about it step by step.

# Test you: 1. Do you really understand the core idea of atomic class? 2. Have you ever used atomic classes directly in your project? 2. Case 2.1. Self-increasing operation case 2.1.1. Normal variable version

Case description:

Define a common int variable value with an initial value of: 0

Start two threads thread_1,thread_2 to execute value++ operation in parallel

5000 execution times per thread, expected execution result: 2 * 5000 = 10000 times

By observing the final implementation result, whether it is equal to the expected 10000 times

The result is not equal, indicating that the thread is not safe. The reason is that the value++ operation is not an atomic operation.

Package com.anan.edu.common.newthread.atomic;/** * ordinary int variable + + operation, non-atomic, thread unsafe * * @ author ThinkPad * @ version 1.0 * @ date, 2020-11-29 8:27 * / public class CommonIntDemo {/ * * ordinary member variable * / private int value = 0; public void addValue () {value++ } public static void main (String [] args) throws InterruptedException {/ / 1. Create a CommonIntDemo object CommonIntDemo demo = new CommonIntDemo (); / / 2. Create 2 two threads, each calling the method addValue 5000 times / / the expected value is equal to: 2 * 5000 = 10000 int loopEnd = 5000; Thread thread_1 = new Thread (()-> {for (int I = 0; I)

< loopEnd; i++){ demo.addValue(); } }, "thread_1"); Thread thread_2 = new Thread(() ->

{for (int I = 0; I)

< loopEnd; i++){ demo.addValue(); } }, "thread_2"); // 3.启动执行线程 thread_1.start(); thread_2.start(); // 4.主线程等待子线程执行完成,打印value值 thread_1.join(); thread_2.join(); System.out.println("int型成员变量value最终结果:" + demo.value); }} 执行结果分析: 2.1.2.AtomicInteger版本 案例描述: 定义一个AtomicInteger变量value,初始值为:0 开启两个线程thread_1,thread_2并行执行value.incrementAndGet()操作 每个线程执行 5000次,预期执行结果: 2 * 5000 = 10000次 通过观察最终执行结果,是否等于预期10000次 结果相等,说明线程安全,原因是:原子类同时满足了可见性、与原子性 package com.anan.edu.common.newthread.atomic;import java.util.concurrent.atomic.AtomicInteger;/** * 原子类AtomicInteger,实现自增操作,线程安全 * * @author ThinkPad * @version 1.0 * @date 2020/11/29 8:27 */public class AtomicIntegerDemo { /** * AtomicInteger成员变量 */ private AtomicInteger value = new AtomicInteger(0); public void addValue(){ value.incrementAndGet(); } public static void main(String[] args) throws InterruptedException { // 1.创建AtomicIntegerDemo对象 AtomicIntegerDemo demo = new AtomicIntegerDemo(); // 2.创建2两个线程,每个线程调用方法addValue 5000次 // 预期value值结果等于:2 * 5000 = 10000 int loopEnd = 5000; Thread thread_1 = new Thread(() ->

{for (int I = 0; I)

< loopEnd; i++){ demo.addValue(); } }, "thread_1"); Thread thread_2 = new Thread(() ->

{for (int I = 0; I)

< loopEnd; i++){ demo.addValue(); } }, "thread_2"); // 3.启动执行线程 thread_1.start(); thread_2.start(); // 4.主线程等待子线程执行完成,打印value值 thread_1.join(); thread_2.join(); System.out.println("AtomicInteger型成员变量value最终结果:" + demo.value); }} 执行结果分析: 2.2.原子类底层原理分析2.2.1.再次分析线程安全核心思想 通过比较普通类型int型变量自增操作,与原子型AtomicInteger型变量自增操作。我们看到应用层代码几乎没有差异,仅仅是通过AtomicInteger替换int实现自增操作,即保证了线程安全。那么AtomicInteger它是如何做到的呢? 要分析清楚AtomicInteger底层原理,还需要回到我们说过的线程安全基本要素:可见性、原子性、有序性。就是说不管通过什么手段,要实现线程安全,一定要满足这三个基本要素,换句话说,满足了三个基本要素,也即实现了线程安全。 那么我们就从这三个要素开始分析。首先看最容易理解的有序性,你还记得什么是有序性吗?它是说线程内有序,线程之间无序。有序性比较好理解,我们就不过多解释了。 再来看可见性,同样你还记得什么是可见性吗?我们知道jmm内存模型,每个线程都有自己的私人空间(工作内存),所有线程共享公共空间(主内存)。那么如果要保证某个变量在线程间的可见性,即当线程A操作该变量后,需要同步将变量值从私人空间同步到公共空间:工作内存--->

Main memory; similarly, other threads need to synchronize the value of the variable from the public space to the private space before manipulating the variable: main memory-> working memory. Java programming syntax provides us with a keyword: volatile. Used to achieve visibility. You may also need the following picture:

Finally, let's take a look at atomicity, atomicity you should remember, we just shared in the last article: advanced concurrent programming series 12 (understand cas). In essence, cas means that you will not die until you reach the Yellow River. What does it mean? That is, the cpu is not released and the operation is cycled until the operation is successful. That's how we explained it, and you should remember it, too. And we also said that for cas, its operation principle is three values: memory value A, expected value B, update value C. Each operation compares the memory value A, whether it is equal to the expected value B, and if so, updates the memory value to the value C, and the operation is successful; if the memory value An is not equal to the expected value B, the operation fails and the next loop operation is carried out. You may also need the following picture:

All right, at this point, we can take a look at the source code of AtomicInteger. See if it satisfies what we call visibility and atomicity. Further analyze the implementation principle of thread safety of AtomicInteger class. Below we use screenshot and text description to make it easier for you to understand.

2.2.2.AtomicInteger class declaration

First, let's take a look at the declaration of the AtomicInteger class, which may be difficult for unfamiliar friends to understand. Let's take a screenshot and take a look.

2.2.3. Methods incrementAndGet analysis

Through the class declaration part of the source code, we see the visibility of thread safety, which is guaranteed by modifying value member variables with the volatile keyword. So how can atomicity be guaranteed? The answer is guaranteed by the cas operation of the Unsafe utility class. Look at the picture:

2.3.juc atomic class classification

I believe that through the above analysis, you have understood the underlying implementation principle of atomic thread safety, and if it is a little difficult for you to understand, I suggest you read it twice. For a programmer, we should not only use the framework, the underlying ideas and principles are the internal work.

So let's put aside the low-level analysis of atomic classes for a while, and let's take a look at the common atomic power utility classes provided in the juc package. The underlying principles of each of them have been analyzed above, so I will no longer analyze them one by one, but simply enumerate them. If you are interested, you can find one or two to analyze by yourself according to the above analysis ideas. There should be unexpected surprises!

Basic atomic class, representative: AtomicInteger, AtomicLong

Array atomic class, representative: AtomicIntegerArray, AtomicLongArray

Refer to the atomic class, representing: AtomicReference. With regard to the reference atomic class, add a little bit: it can package an ordinary object as an object with atomic power.

Provide upgrade capability atomic class, representative: AtomicIntegerFieldUpdater, AtomicLongFieldUpdater

Accumulator atomic class, representing: LongAdder. With regard to the accumulator, add a little more: it is a new partner after the start of jdk1.8, and its performance is more leveraged than that of AtomicLong.

This is the end of the content of "what is the Atomic Class of the Advanced concurrent programming Series". 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