Java Concurrency Programming Guide (6): Concurrent Collections

1. Non-blocking thread-safe list  ConcurrentLinkedDeque

Concurrent lists allow different threads to add() or remove pollFirst(), pollLast() elements of the list at the same time without any data inconsistencies (problems).

  • add(), addFirst(), addLast(): These methods allow to insert an element at the beginning or end of the list. An exception will be thrown if there is no free space.
  • poll(), pollFirst() and pollLast() : These methods will return the first and last element of the list respectively. and remove the returned element from the list. Returns null if the list is empty.

  • get(), getFirst() and getLast() : These methods will return the first and last element of the list respectively. They do not remove the returned element from the list. These methods will throw a NoSuchElementExcpetion exception if the list is empty.
  • peek(), peekFirst() and peekLast() : These methods will return the first and last elements of the list respectively. They do not remove the returned element from the list. These methods will return a null value if the list is empty.
  • remove(), removeFirst(), removeLast() : These methods will return the first and last element of the list respectively. They will remove the returned element from the list. These methods will throw a NoSuchElementExcpetion exception if the list is empty.

2, Blocking thread-safe list LinkedBlockingDeque

  • The put() method adds an element to the list. If the list is full, this method blocks execution of the thread until the list has space available.
  • The take() method takes the string from the list. If the list is empty, this method will block the execution of the thread until there is an element in the list.
  • takeFirst() and takeLast(): These methods return the first and last element of the list respectively. They remove the returned element from the list. If the list is empty, these methods will block the thread until the list has elements.
  • getFirst() and getLast(): These methods return the first and last elements of the list respectively. They do not remove the returned element from the list. These methods will throw a NoSuchElementExcpetion exception if the list is empty.
  • peek(), peekFirst(), and peekLast(): These methods return the first and last elements of the list, respectively. They do not remove the returned element from the list. These methods will return a null value if the list is empty.
  • poll(), pollFirst() and pollLast(): These methods return the first and last elements of the list respectively. They remove the returned element from the list. These methods will return a null value if the list is empty.
  • add(), addFirst(), addLast(): These methods add elements at the first and last positions respectively. These methods will throw an IllegalStateException if the list is full (you created it with a fixed size).


3. Sort the list using blocking thread safety by priority PriorityBlockingQueue



4. Use a thread-safe list with delayed elements DelayedQueue

The DelayedQueue class is an interesting data structure provided by the Java API and which you can use in concurrent applications. In this class you can store elements with activation date. Unexpired data elements are ignored by methods returning or extracting elements of the queue. They are invisible to these methods.
In order to obtain this behavior, the elements you want to store into the DelayedQueue class must implement the Delayed interface. This interface allows you to deal with delayed objects, so you will implement the activation date stored in the DelayedQueue object, and this activation period will be used as the remaining time of the object until the activation date comes. This interface enforces the implementation of the following two methods:
  • compareTo(Delayed o): The Delayed interface inherits the Comparable interface.
  • getDelay(TimeUnit unit): This method returns the remaining delay time associated with this object, expressed in the given time unit. When the return value is less than or equal to 0, the element expires.

5. Create concurrent random numbers ThreadLocalRandom

The Java Concurrency API provides specified classes to generate pseudorandoms in concurrent applications. It is the ThreadLocalRandom class, which is new in the Java 7 version. It uses thread local variables. Each thread expects to generate random numbers with a different generator, but they are managed from the same class, which is transparent to the programmer. With this mechanism, you will get better performance than using a shared Random object to generate random numbers for all threads.
The ThreadLocalRandom class also provides methods to generate numbers of type long, float, and double, as well as Boolean values. These methods allow you to pass a number as a parameter and generate a random number between 0 and this number. There are other methods that allow you to pass in two parameters and generate a random number between the values ​​of the two parameters.


6. Use atomic variables, atomic arrays

AtomicInteger, AtomicLong, AtomicBoolean,AtomicIntegerArray, AtomicLongArray等

When you implement a concurrent application where multiple threads share one or more objects, you need to use locks or synchronization keywords (such as synchronized) to protect access to their properties to avoid data inconsistencies caused by concurrency. mistake.
However, these mechanisms have the following disadvantages:

  • Deadlock (dead lock): For example: when a thread is waiting for a lock, it will be blocked, and the lock is occupied by other threads and never released. This situation is a deadlock, in which the program will never proceed.
Even if only one thread is accessing the shared object, it executes the necessary lock-acquisition and lock-release code.

The CAS (compare-and-swap) operation provides better performance for concurrent operation objects. The CAS operation implements the following three steps to modify the variable value:
  • The CPU obtains the value of the variable in the current memory, which is the old value of the variable.
  • The CPU uses a new temporal variable to store the changed new value
  • If the current value in memory is equal to the old value of the variable, assign the new value to the current variable; otherwise, do nothing. Because other threads may have modified the value of the variable so that the old value has been inconsistent with the value in memory.
For this mechanism, you don't need to use any synchronization mechanism, so you avoid deadlocks and also get better performance. This mechanism ensures that multiple concurrent threads operate on a shared variable with eventual consistency.

Java implements the CAS mechanism in atomic classes. These classes provide the compareAndSet() method; this method is the basis for the implementation of CAS operations and other methods.

Atomic Array is also introduced in Java to implement the operation of Integer type and Long type array.



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325947862&siteId=291194637