[High Concurrency Java 1] Preface

 This series is based on the course of alchemy and gold. For better learning, a series of records have been made. This article mainly introduces 1. The concept of high concurrency, to pave the way for the future series of knowledge. 2. Two important theorems

1. Several important concepts about high concurrency

1.1 Synchronous and asynchronous

First of all, the synchronization and asynchrony mentioned here refer to the function/method invocation aspect.

Obviously, the synchronous call will wait for the return of the method, and the asynchronous call will return instantly, but the instant return of the asynchronous call does not mean that your task is completed, it will start a thread in the background to continue the task.

1.2 Concurrency and Parallelism

Concurrency and parallelism are similar in appearance. As shown in the figure, parallelism means that two tasks are carried out at the same time, and concurrency means that one task will be done for a while and then another task will be switched. Therefore, a single CPU cannot be parallelized, only concurrent.

1.3 Critical Sections

A critical section is used to represent a common resource or shared data, which can be used by multiple threads, but at a time, only one thread can use it. Once the critical section resource is occupied, other threads want to use this resource, Have to wait.

1.4 Blocking and non-blocking

  • Blocking and non-blocking usually describe the interaction between multiple threads. For example, if a thread occupies a critical section resource, then all other threads that need this resource must wait in this critical section, and waiting will cause the thread to hang. This situation is blocking. At this point, if the thread occupying the resource has been unwilling to release the resource, then all other threads blocked in this critical section cannot work.
  • Non-blocking allows multiple threads to enter the critical section at the same time

Therefore, the blocking method, the general performance is not very good. According to general statistics, if a thread is suspended at the operating system level and a context switch is performed, it usually takes 8W time cycles to do this.

1.5 Deadlock, starvation, livelock

The so-called deadlock : refers to a phenomenon of blocking caused by competing for resources or communicating with each other during the execution of two or more processes. If there is no external force, they will not be able to advance. At this time, the system is said to be in a deadlock state or the system has a deadlock, and these processes that are always waiting for each other are called deadlock processes. Just like the car in the picture below wants to move forward, but no one can move forward.

But deadlock is a bad phenomenon, but it is a static problem. Once a deadlock occurs, the process is stuck, and the CPU occupancy rate is also 0. It will not occupy the CPU, and it will be transferred out. It is relatively easy to find and analyze.

The counterpart to deadlock is livelock.

Livelock means that Thing 1 can use resources, but it allows other things to use resources first; Thing 2 can use resources, but it also allows other things to use resources first, so both have been humble and cannot use resources.

For example, it's like you meet someone on the street, and he happens to be walking in the opposite direction of you and encounters you head-on, and you both want to pass each other. You move to the left, he moves to the left, and the two still cannot pass. Then you move to the right, he moves to the right, and so on.

When a thread acquires a resource, it finds that other threads also think of this resource, because it does not get all the resources, in order to avoid deadlock, it gives up all the resources it holds. If another thread does the same thing, they need the same resources. For example, A holds the a resource and B holds the b resource. After giving up the resource, A gets the b resource again, and B gets the a resource, so Repeatedly, a livelock occurs.

Livelocks are harder to detect than deadlocks because livelocks are a dynamic process.

Starvation refers to the fact that one or more threads cannot obtain the required resources for various reasons, resulting in the inability to execute.

1.6 Concurrency levels

Concurrency level: blocking and non-blocking (non-blocking is divided into barrier-free, lock-free, and wait-free)

1.6.1 Blocking

When a thread enters a critical section, other threads must wait

1.6.2 Accessibility

  • Accessibility is the weakest non-blocking schedule
  • Free access to critical sections
  • When there is no competition, the operation is completed in a limited number of steps
  • When there is contention, roll back data

Compared with non-blocking scheduling, blocking scheduling is a pessimistic strategy. It will think that modifying the data together is likely to corrupt the data. Instead of blocking scheduling, it is an optimistic strategy. It believes that everyone modifying the data may not necessarily change the data. But it is a policy of lenient in and strict out. When it finds that a process has data competition in the critical area and a conflict occurs, the barrier-free scheduling method will roll back this data.

In this hassle-free scheduling method, all threads are equivalent to taking a snapshot of the current system. They'll keep trying to take the snapshot until it's valid.

1.6.3 No lock

  • is accessible
  • One thread is guaranteed to win

In contrast to accessibility, accessibility does not guarantee that the operation will be completed in the presence of contention, because if it finds that every operation creates a conflict, it will keep trying. If the threads in the critical section interfere with each other, all threads will be stuck in the critical section, and the system performance will be greatly affected.

The lock-free adds a new condition to ensure that one thread can win each competition, which solves the problem of accessibility. At least ensure that all threads are executed smoothly.

The following code is a typical lock-free calculation code in Java

Lockless is common in Java

?
1
2
3
4
while (!atomicVar.compareAndSet(localVar, localVar+ 1 ))
{
     localVar = atomicVar.get();
}

1.6.4 No wait

  • lock-free
  • Requires that all threads must complete within a finite number of steps
  • hungry

First of all, the premise of no waiting is on the basis of no locks. Without locks, it only ensures that there must be in and out of the critical section, but if the priority of entering is high, then some low-priority threads in the critical section may be Starvation occurs, and it has been unable to get out of the critical zone. Then no wait solves this problem, it guarantees that all threads must be completed within a limited number of steps, and naturally there is no starvation.

No wait is the highest level of parallelism, and it enables this system to be optimal.

Typical case of no waiting:

If there are only read threads and no thread threads, then this must be wait-free.

If there are both reading threads and writing threads, and each writing thread copies a copy of the data before modifying the copy, instead of modifying the original data, because if the copy is modified, there is no conflict, then the modification process is also No waiting. The last thing that needs to be synchronized is to overwrite the original data with the written data.

Because the requirement of no waiting is relatively high and it is difficult to implement, the use of lock-free will be more extensive.

2. Two important laws about parallelism

Both of these laws are related to the speedup ratio

2.1 Amdahl's Law

The calculation formula and theoretical upper limit of the speedup ratio after parallelization of the serial system are defined

Speedup ratio definition: Speedup ratio = system time before optimization / system time after optimization

for example:

Speedup ratio = system time before optimization / system time after optimization = 500/400 = 1.25

This theorem shows that increasing the number of CPU processors does not necessarily play an effective role in increasing the proportion of modules that can be parallelized in the system. Only by reasonably increasing the number of parallel processors can the maximum speedup ratio be obtained with the smallest investment.

2.2 Gustafson's Law

Explain the relationship between the number of processors, serial ratio and speedup ratio

Then the speedup ratio=nF(n-1) //The derivation process is omitted

As long as there is enough parallelization, the speedup is proportional to the number of CPUs

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326975688&siteId=291194637