🎓 Do your best and obey the destiny. The blogger is studying for a master’s degree in Southeast University. He loves fitness and basketball, and is willing to share what he sees and gains related to technology. He pays close attention to the public account @flying Veal, and gets the update of the article as soon as possible

🎁 This article has been included in the “CS-Wiki” Gitee official recommended project, has accumulated 1.6K + STAR, is committed to creating a perfect back-end knowledge system, in the road of technology to avoid detours, welcome friends to come to exchange and study

🍉 If you do not have a good project, you can refer to a project I wrote “Open source community system Echo” Gitee official recommended project, so far has accumulated 600+ star, SpringBoot + MyBatis + Redis + Kafka + Elasticsearch + Spring Security +… And provide detailed development documents and supporting tutorials. Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo


I have wanted to write this article for a long time, but I have not dared to write it. On the one hand, I have insufficient knowledge reserve in the past, and on the other hand, it is mainly multithreading. This part is really advanced and scattered among each knowledge point, making people confused and do not know where to start. And for us students, there are few opportunities to access the real scene of high concurrency, and we usually don’t use it when we type code. Therefore, most of our students are learning from the face to face. You ask synchronized, volatile, and I can say a lot of them. But the total feeling almost means, is that these knowledge points are scattered, there is not a line to connect them well.

So today I dare to make a line, stand in the small white point of view, talk about multi-threaded this part we exactly want to learn what, according to what kind of order to learn, to help you establish a more perfect knowledge system, the formation of a correct multi-threaded world view. I’ll basically follow this line for the rest of my articles.

Then, I did not step into the work post at present, also do not have the actual high concurrency experience, so just on paper, knowledge is shallow, if the big guys feel that there is a problem, please comment area or private chat I correct, the younger generation is grateful (fist).

gas

First of all, to learn about multithreading, you must know what a thread is, including some basic concepts of threads (such as context switching), so talking about threads, certainly can not leave the process. OK, process and thread are two concepts that we have been exposed to in the operating system course, of course, you have also learned the basic concepts of parallel and concurrent, synchronous and asynchronous, so you also need to understand the difference between Java threads and operating system threads.

In addition, it is easy to be overlooked that the emergence of a technology must not be invented, he must come for a purpose, in a mature time came into being. So, you need to know why we use multithreading, and what problems it solves.

Master the above step, we call it refining gas, refining refined gas, the initial stage needs to be single-minded, calm.

The preconditions

Now that we know what a thread is, how do you create one in Java? To do this, you’ll be exposed to three ways of creating threads:

  • Using Thread directly
  • Thread + Runnable
  • Thread + Callable + FutureTask

After learning how to create a Thread, we go to the source of the Thread class, you will find that it defines the Java Thread six states, also known as the so-called life cycle, it and the operating system Thread five state model and what is the difference and connection?

Since we have turned over the Thread source code, there is no reason not to explore the truth? Let’s take a look at the methods Thread provides for controlling threads, what they do, and how they affect Thread state:

  • start / run
  • sleep / yield
  • join / join(long n)
  • interrupt
  • SetDaemon Daemon thread

This stage of learning, the first step after the introductory stage, is called foundation building. The foundation is weak and the earth shakes.

then

Of course, there is nothing inherently wrong with a program running multiple threads sequentially. However, if multiple threads access a shared resource at the same time, unpredictable phenomena can occur. This is often referred to as thread safety problems. We need to deeply understand the Java Memory Model (JMM).

To do this, we’ll learn about three properties that are relevant to thread safety:

1) Atomicity: an operation is not interruptible, either all the operations succeed or all the operations fail (also can be said to provide mutually exclusive access, only one thread can operate on data at a time)

2) Visibility: When one thread changes a shared variable, other threads are immediately aware of the change

3) Orderliness (or reordering) : Reordering is a method by which compilers and processors reorder instruction sequences to optimize program performance. Due to the existence of reordering, it may lead to the error of the program running results in multi-threaded environment.

So what principles do compilers and processors follow when reordering? To do this, you’ll learn about data dependencies and as-IF-Serial. Here’s a brief introduction to these two concepts:

  • Compilers and processors comply with data dependencies when reordering, and they do not change the order in which two operations are executed in a data dependency relationship
  • The as-if-serial semantics mean that the execution result of a program cannot be changed no matter how reordered it is. The compiler, runtime, and processor must comply with the AS-IF-Serial semantics

In fact, visibility and order are two contradictory points. On the one hand, we want the memory model to be easy for programmers to understand and program, and for that reason the DESIGNERS of the JMM provide programmers with a strong enough guarantee of memory visibility, known in the jargon as a “strong memory model.” Compilers and processors, on the other hand, want the memory model to tie them down as little as possible so that they can make as many optimizations (such as reordering) to improve performance, so the JMM designers have to be as loose as possible on the compiler and processor, known in the jargon as the “weak memory model.”

Of course, the JMM designers found a good balance on this issue, happens-before, which is the core concept of the JMM! Understanding happens-before is key to understanding the JMM.

We call this stage golden Dan.

Crossing the bullet

Specifically at the Java language level, how to ensure thread safety? How do you guarantee atomicity, visibility, and order? (To ensure order, as mentioned above, is to use the happens-before principle).

1) For visibility, use the volatile keyword. In addition, volatile can prevent instruction reordering;

2) for atomicity, we can use the lock and Java. Util. Concurrent. The atomic package of atoms in the class to guarantee. Java.util.concurrent (J.U.C. for short) is a package, also known as a concurrent package. Most of the blogs on the web will just say JUC, which is not very friendly), we can look at the JUC.

Of course, the most important reason for atomic operation classes to ensure atomicity is that they use CAS operation. Therefore, you need to learn CAS in depth first, understand the three problems existing in CAS, and then dig into the underlying principles of these atomic classes.

In addition, the topic of locks mentioned above is actually a very core knowledge point, before further study, you need to understand the concept of various locks:

  • Pessimistic locks and optimistic locks
  • Heavyweight and lightweight locks
  • spinlocks
  • Biased locking
  • Reentrant locks and non-reentrant locks
  • Fair locks and unfair locks
  • Shared and exclusive locks

In addition, there are concepts related to locking, such as critical sections, race conditions, and so on, which you have to understand.

How does locking work in Java? In the early Java programs, synchronized keyword was used to implement the lock function. After we master the usage and basic principle of synchronized, you will also come into contact with the wait/notify/notifyAll methods matching synchronized.

After Java SE 5, and added a contract awarding JUC Lock interface and related implementation class (in Java. Util. Concurrent. The locks package) can also be used to realize the Lock function.

Why was such a Lock interface and its associated implementation class added? The synchronized keyword implicitly acquires the lock, but it solidifies the acquisition and release of the lock, i.e. Of course, this approach simplifies synchronization management, but scalability is not as good as explicit lock acquisition and release.

For example, for A scenario, lock acquisition and release are carried out hand by hand. Lock A is acquired first, and then lock B is acquired. When lock B is acquired, lock A is released and lock C is acquired; when lock C is acquired, lock D is acquired and so on. In this scenario, the synchronized keyword is not as easy to implement as the Lock keyword.

It provides synchronization functionality similar to that of the synchronized keyword, except that locks are explicitly acquired and released when used. Although it lacks the convenience of implicit lock acquisition and release, it has the operability of lock acquisition and release, the ability to interrupt lock acquisition and timeout lock acquisition and other synchronization keywords do not have the synchronization characteristics.

In addition, there is a very important point! If you take a look at a class that implements the Lock interface, such as ReentrantLock (which most articles translate as ReentrantLock), you’ll be surprised to find that it doesn’t have much code, and basically all of its methods call methods from its static inner class Sync. And Sync inherited AbstractQueuedSynchronizer class (i.e., the well-known AQS, translated into queue synchronizer, synchronizer for short).

You can think of AQS as a framework for building locks and synchronizers (utility classes), and the various locks in the LOCKS package and the utility classes in JUC that we’ll learn about later are implemented based on AQS.

OK, no more talk about AQS in this article. Synchronized and volatile are the same concurrency keywords as final. What does final have to do with concurrency? Of course, this will be covered in subsequent articles.

This stage of knowledge is very important, and relatively more knowledge is more difficult, so we call it the transit.

mahayana

You have a certain understanding of the basic knowledge structure of multithreading, and the world view has been preliminarily formed. Finally, it is the process of strengthening, we will look at J.U.C. this package still has what things (the picture below is not full) :

JUC can actually be divided into five categories:

  • Lock Framework (LOCKS package)
  • Atomic package
  • Concurrent collections
  • The thread pool
  • Utility class

The last three are exactly what we need to learn at this stage. Concurrent collections and thread pools are not much to be said for their concentration of knowledge and specific learning objectives, and it is easy to find a well-organized article on the Web.

Then it is necessary to learn the common tool class:

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • Exchanger

A utility class encapsulates some of the more complex operations that can be done easily. Take CountDownLatch as an example: In a multithreaded collaborative business function, sometimes need to wait for other threads to complete the task, the main Thread to continue to perform business functions, in this business scenario, usually can use the join method of the Thread class, make the main Thread waiting to be join after a Thread execution, the main Thread to continue to perform. The Java concurrency utility class provides us with a “countdown” like utility class CountDownLatch, which can be very convenient to complete this business scenario.

Another important class that I don’t know how to categorize is ThreadLocal.

OK, after learning this stage, multi-threaded world view has been completely formed, we call it mahayana, the land of selflessness, all in your own mind.

| flying veal 🎉 pay close attention to the public, get updates immediately

  • The blogger is a master student in Southeast University. In her spare time, she runs a public account “Flying Veal”, which was opened on December 29, 2020/29. Focus on sharing computer basics (data structure + algorithm + computer network + database + operating system + Linux), Java basics and interview guide related original technical good articles. The purpose of this public account is to let you can quickly grasp the key knowledge, targeted. I hope you can support me and grow with veal 😃
  • And recommend personal maintenance of the open source tutorial project: CS-Wiki (Gitee recommended project, has accumulated 1.6K + STAR), is committed to creating a perfect back-end knowledge system, in the road of technology to avoid detdettions, welcome friends to come to exchange learning ~ 😊
  • If you don’t have any outstanding projects, you can refer to the Gitee official recommended project of “Open Source Community System Echo” written by me, which has accumulated 600+ star so far. SpringBoot + MyBatis + Redis + Kafka + Elasticsearch + Spring Security +… And provide detailed development documents and supporting tutorials. Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo Echo