java. util. Detailed analysis of concurrent package — transfer
Original address: http://blog.csdn.net/windsunmoon/article/details/36903901
summary
. util. Concurrent contains many thread safe, good, and high-performance concurrent building blocks. To put it bluntly, create Java util. The purpose of concurrent is to realize the concurrent operation performed by the collection framework. By providing a set of reliable and high-performance concurrent building blocks, developers can improve the thread safety, scalability, performance, readability and reliability of concurrent classes.
CAS is used in all of them (compare and swap) operation. CAS is a low-level, fine-grained technology that allows multiple threads to update a memory location and detect and recover conflicts of other threads. It is the basis of many high-performance concurrency. Before JDK 5.0, the only primitive used to coordinate access between threads in the Java language was synchronization, which is more heavyweight and coarse-grained Degrees. Exposing CAS can develop highly scalable concurrent Java classes. These changes are mainly used by JDK library classes, not by developers.
Atomic atomic data
Scalar class
The first group of four basic types, atomicboolean, atomicinteger, atomiclong and atomicreference, are used to process Boolean, integer, long integer and object data. Their internal implementation is not simply synchronized, but a more efficient CAS (compare and swap) + volatile and native methods, so as to avoid the high overhead of synchronized, The execution efficiency has been greatly improved.
Array class
Updater class
(2) The description type of the field (modifier public / protected / default / private) is consistent with the relationship between the caller and the operation object field. That is, if the caller can directly operate the object field, it can reflect the atomic operation. However, for the field of the parent class, the subclass cannot operate directly, although the subclass can access the field of the parent class.
Compound variable class
Lcoks lock
The most basic lock implemented in this package is locksupport that blocks threads. The core is AQS framework (abstractqueuedsynchronizer), which is the most complex class of j u c (util concurrent).
Lock and synchronized
Lock and synchronized in j u c have the same semantics and functions. The difference is that the synchronized lock is automatically released when the block is exited. The lock needs to be released manually, and the lock is more flexible. Syscronizd is at the Java language level and is a system keyword; Lock is a class provided since Java 1.5.
Locksupport and Java built-in locks
What is the difference between locksupport and the built-in monitor mechanism of the Java language? Their semantics are different. Locksupport performs block / unblock operations for a specific thread; Wait() / notify() / notifyall() is used to manipulate the waiting collection of specific objects. In order to prevent knowledge from rusting, here is a brief introduction to the built-in monitor mechanism of Java language (see:). Just as every object has a lock, Each object also has a wait set. It has wait, notify, notifyAll and thread.interrupt methods to operate. Entities that have both locks and wait sets are usually called monitors (monitor). The wait collection of each object is maintained by the JVM. The wait collection always stores threads blocked by calling the wait method of the object. Due to the interaction mechanism between the wait collection and the lock, its wait, notify and notifyAll methods can be called only when the synchronization lock of the target object is obtained. This requirement can not be checked by compilation. If If the condition cannot be met, calling the above method at runtime will cause it to throw illegalmonitorstateexception.
In the standard sun JDK, the implementation of locksupport is based on unsafe, which is all local code, and the implementation of locksupport is not all local code.
AbstractQueuedSynchronizer
The AQS framework is the core of the j u c package. It is the basis for building synchronization, locks, semaphores, and custom locks. It is also the basis for building advanced tools.
In short, abstractqueuedsynchronizer will form all request threads into a CLH queue. When a thread completes execution (lock. Unlock()), it will activate its successor nodes, but the executing threads are not in the queue, and all the threads waiting for execution are blocked. After investigation, the explicit blocking of threads is through calling locksupport Park() completed, while locksupport Park() calls sun misc. Unsafe. Park () is a local method. Further, hotspot calls pthread in_ mutex_ The lock function gives the thread to the system kernel for blocking.
reentrantlock
Condition
Condition implements functions similar to Java content monitor. Provide await, signal, signalall and other operations, and object Wait and a series of operations. The difference is that a condition can have multiple condition queues. The built-in monitor cannot do this. In addition, more flexible methods such as timeout and cancellation are supported.
Like the built-in monitor, condition is called. Await and other operations need to obtain a lock, that is, condition is bound with a lock. Its implementation is in AQS. The basic idea is as follows: copy the following content from the blog:
Thread pool
The implementation of thread pool is provided in JUC, which is based on a series of abstractions and interfaces. Next, step by step, unlock the mystery of thread pool.
First, you should understand the use of thread pools. J u c provides a factory class for constructing thread pool. java. util. concurrent. Executors 。 This factory provides static methods for constructing various types of thread pools. Such as fixed thread pool, single worker thread pool, and cache thread pool.
The following code constructs a thread pool with 2 fixed worker threads.
Interface executor
The interface has only one method. The JDK explains it as follows
The object that executes the submitted runnable task. This interface provides a method to separate task Submission from the mechanism of how each task will run (including details of thread usage, scheduling, etc.).
void execute( command)
Execute the given command at some time in the future. The command may be executed in a new thread, a pooled thread, or a calling thread, which is determined by the executor implementation.
Interface executorservice
Executorservice is an extension of executor. The JDK document explains as follows:
Provides methods for managing termination and methods that can be generated to track the execution of one or more asynchronous tasks.
, the method submit extends the basic method. Methods invokeany and invokeall are the most common forms of batch execution. They execute task collection and wait for at least one or all tasks to complete (you can use classes to write custom variants of these methods).
The key in this interface is the three submit methods, which accept a task and return the result future.
Callable is the runnable with the returned result. It is defined as follows:
The wonderful thing is to return a future that represents the pending results of the task. The get method of the future will return the result of the task upon successful completion. Note that these processes are asynchronous.
Interface future
JDK is explained as follows:
Future represents the result of asynchronous calculation. It provides a method to check whether the calculation is completed, so as to wait for the completion of the calculation and obtain the results of the calculation. After the calculation is completed, you can only use the get method to obtain the results. If necessary, you can block this method before the calculation is completed. Cancel is performed by the cancel method. Other methods are also provided to determine whether the task is completed normally or cancelled. Once the calculation is completed, you cannot cancel the calculation. If you use future for cancellability but do not provide available results, you can declare the future formal type and return null as the result of the underlying task.
What happened after submit
With the above basic understanding, let's look at a series of processes that occur after the task is submitted.
The actual code of submit is located in abstractexecutorservice, which inherits executorservice. To observe its three submit methods.
Construct runnablefuture
It can be seen that no matter what the parameters of the submit method are, a runnablefuture is constructed first, then it is executed and returned. Runnablefuture is executed and returned. Therefore, runnablefuture implements the future interface and runnnable interface. Note that the type of this point is runnablefuture. The run method executed by all subsequent execute methods is the run method of the specific implementation class futuretask of runnablefuture.
As. Successful execution of the run method completes the future and allows access to its results. The following code shows that the returned is actually futuretask, which is the implementation class of runnablefuture.
Cancelable asynchronous calculation. Using the methods of starting and canceling calculation, querying whether the calculation is completed, and obtaining the calculation results, this class provides the basic implementation of. The results can be obtained only when the calculation is completed; The get method is blocked if the calculation has not been completed. Once the calculation is completed, you cannot restart or cancel the calculation.
You can use futuretask to wrap or objects. Because futuretask implements runnable, futuretask can be submitted to execution.
implement
Next, let's look at performing tasks. The execute method is implemented in the ThreadPoolExecutor class, which is a specific thread pool. The execute method is as follows:
Implementation 1
Let's look at situation 1 first. The following code adds a new worker thread only when the current pool size is less than the core pool size and the thread pool is in the running state, and takes the transmitted task as the first task and starts execution. It returns true at this time, otherwise it returns false.
Implementation 2
If the current pool size is larger than the core pool size, or adding a new worker thread fails (this may be that in a multi-threaded environment, it competes for locks, is blocked, and other threads have created worker threads), then the current task enters the waiting queue.
If the queue is full or the thread pool is closed, the task is rejected.
Worker thread
The encapsulation of the worker thread is the worker class, which implements the runnable interface. The addthread method forms workers into threads (using threadfactory), adds them to the thread pool, and resets the maximum size of the thread pool.
FutureTask
This class is the implementation class of runnablefuture. The run method executed by the thread pool is its run method. It is delegated to sync implementation, and sync inherits AQS.
reference resources
Principle of lock