Concurrent container - list and Set copied on write
CopyOnWriteArrayList
There are problems with the synchronized container. One of them is that when the composite operation is hungry (for example, check first and then update), the caller also needs to lock.
The interior of CopyOnWriteArrayList is also an array. Each modification operation will create a new array, copy the contents of the original array to the new array, make the necessary modifications on the new array, and then set the internal array reference in an atomic way, which is copy on write.
Bottom line: the contents of the array are read-only. Write operations are implemented by creating a new array and atomically modifying the array reference.
Reads do not require locks and can be parallel. Read and write can also be parallel, but only one write thread is allowed.
/** The lock protecting all mutators */ final transient ReentrantLock lock = new ReentrantLock(); /** The array, accessed only via getArray/setArray. */ private transient volatile Object[] array;
Look at the add method
public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); } }
The goal is to optimize the read operation, which sacrifices the write performance while optimizing the read operation.
There are two ways to ensure thread safety. One is locking, using synchronized or ReentrantLock, and the other is circular CAS. Copy on write provides another idea to ensure thread safety.
**Both lock and cyclic CAS control access conflicts to the same resource, while write time replication reduces conflicts by replicating resources** Suitable for reading more and writing less. It is a good solution.
CopyOnWriteArraySet
From the source code, we can see that CopyOnWriteArraySet is implemented based on CopyOnWriteArrayList. Compared with HashSet and TreeSet, the performance is low.
Simple summary: copy while writing is an important thinking and technology in computer programs.
ConcurrentHashMap
Features 1 - concurrency security, directly supporting some atomic composite operations, 2, - supporting high concurrency, parallel read operations, and parallel write operations to a certain extent. 3 - compared with the synchronization container synchronizedMap, the iteration does not need to lock and does not throw ConcurrentModificationException, 4, - weak consistency
Under Java 7 HashMap multithreading, there will be an endless loop problem (the problem of chain header interpolation)
java8 has been modified to tail interpolation, but the concurrent modified data will be overwritten
Interface: Java util. concurrent. ConcurrentMap
The basic mechanism of concurrent HashMap to achieve high concurrency
- Sectional lock
- No lock is required for reading
ConcurrentHashMap uses segment lock technology to divide the data into multiple segments, and each segment has an independent lock.
Weak consistency of ConcurrentHashMap
After the iterator of ConcurrentHashMap is created, it will traverse each element according to the hash table structure. However, during the traversal process, the internal elements may change. If the change occurs in the traversed part, the iterator will not reflect it. Otherwise, it will reflect it.
map and set based on hop table
The Concurrent Versions corresponding to TreeMap and TreeSet in the java Concurrent package are: ConcurrentSkipListMap and ConcurrentSkipListSet.
characteristic
1 - no lock is used and all operations are non blocking. All operations can be parallel, including write.
2-weak consistency. Some methods are not atomic, such as putAll and clear
The jump list is based on the linked list, and a multi-layer index structure is added on the basis of the linked list.
In order to achieve concurrency, security, efficiency, lock free and non blocking, the implementation of ConcurrentSkipListMap is very complex.
Concurrent queue
Lock free and non blocking: concurrency security is mainly realized through cyclic CAS.
Blocking queues: these queues all use locks and conditions. Many operations need to obtain the lock first or meet specific conditions. If the lock cannot be obtained, it will wait.
The algorithm of ConcurrentLinkedQueue is based on a paper. If you are interested, see the following link, Refer to other people's blogs
Normal blocking queue
Note: all normal blocking queues are implemented based on ReentrantLock and explicit Condition.
Example: the implementation of ArrayBlockingQueue: an array storage element with two conditions of dissatisfaction and non emptiness for cooperation, which is similar to the implementation of producer consumer mode with explicit conditions.
Asynchronous task execution service
Purpose: to separate task execution from task submission., We need to understand this kind of thinking.
Runable and Callable -- indicates the asynchronous task to be executed
Executor and ExecutorService – represents an execution service
Future: represents the result of an asynchronous task
Runable returns no results and does not throw an exception. Callable will.
Thread pool
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
Precautions during use:
1 - if it is a bounded queue and maxPoolSize is infinite, too many threads will be created and occupy the CPU and memory
2 - if it is an unbounded queue, task s that cannot be serviced are always queued, resulting in excessive memory consumption.
Note: in a scenario with a large number of tasks, allowing the rejection policy to be executed is an aspect of ensuring the stability of the system.
Deadlock of thread pool: there are dependencies between thread pool tasks, and deadlock may occur.
Example: during the execution of task A, A task B is submitted to the same task execution service, but it needs to wait for the end of task B.
Resolution: use SynchronousQueue
In the case of multithreading, the thread pool is preferred.
Timed task
Application scenario:
1 - alarm clock program or task reminder
2 - monitoring system. For example, collect system data every period of time and alarm for abnormal events
3 - statistical system. Make statistics of various data indicators of yesterday at a certain time in the morning
Java implementation
Timer, TimerTask, and ScheduledExecutorService under JUC package
/**TimerTask Delayed task * @author root */ public class TimerFixedDelay { static class LongRunningTask extends TimerTask{ @Override public void run() { try { Thread.sleep(5_000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("long running finished"); } } static class FixedDelayTask extends TimerTask{ @Override public void run() { System.out.println(System.currentTimeMillis()); } } public static void main(String[] args) { Timer timer = new Timer(); timer.schedule(new LongRunningTask(),10); timer.schedule(new FixedDelayTask(),1000); } }
Timer is mainly composed of task queue and timer thread. Task queue is a priority queue based on heap, which is prioritized according to the next execution time. It should be emphasized that a timer object has only one timer thread. This also means that timed tasks cannot take too long, let alone infinite cycles.
/** * Timer Dead cycle * */ public class EndlessLoopTimer { static class LoopTask extends TimerTask{ @Override public void run() { while (true){ try { // Simulate execution of tasks Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } } // There will never be a chance to execute static class ExampleTask extends TimerTask{ @Override public void run() { System.out.println("hello"); } } public static void main(String[] args) { Timer timer = new Timer(); timer.schedule(new LoopTask(),10); timer.schedule(new ExampleTask(), 100); } }
The first scheduled task is an infinite loop, and the subsequent scheduled tasks, exampleTask, will have no chance to execute.
A very important point: when executing the run method of any task, once the run throws an exception, the Timer thread will exit, so that all scheduled tasks will be cancelled.
Summary: Timer and TimerTask are not recommended.