Java Multithreading: Thread-safe and non-thread-safe collection objects

1. Concept:

  • Thread safety: when multi-threaded access, a locking mechanism is used; that is, when a thread accesses a certain data of this class, the data will be protected, and other threads cannot access it until the thread finishes reading After that, other threads can use it. Prevent data inconsistencies or data contamination.
  • Thread unsafe: Data protection is not provided during data access, and multiple threads can operate a certain data at the same time, resulting in data inconsistency or data pollution.
  • For thread unsafe problems, the synchronized keyword is generally used to lock synchronization control.
  • The working principle of thread safety: There is a main memory object in the jvm, and each thread also has its own working memory. When a thread operates on a variable variable, it needs to create a copy in its own working memory, and then write it after the operation. into main memory.
    When multiple threads operate on the same variable, unpredictable results may occur.
    The key to using synchronized is to establish a monitoring monitor, which can be a variable to be modified, or other objects (methods) that it deems appropriate, and then achieve thread safety by locking the monitor. After this lock, the process of loading load to working memory to use && assigning assign to storage store and then to main memory should be executed. will release the lock it acquired. This achieves the so-called thread safety.

2. Thread-safe collection objects:

  • Vector thread safety:
  • HashTable thread safety:
  • StringBuffer thread safety:

3. Non-thread-safe collection objects:

  • ArrayList :
  • LinkedList:
  • HashMap:
  • HashSet:
  • TreeMap:
  • TreeSet:
  • StringBulider:

4. Comparison of related collection objects:

  • Vector, ArrayList, LinkedList:
    1. Vector:
    Like ArrayList, Vector is also implemented through arrays. The difference is that it supports thread synchronization, that is, only one thread can write Vector at a time, avoiding inconsistencies caused by simultaneous writing by multiple threads. , but it is expensive to implement synchronization, so accessing it is slower than accessing ArrayList.
    2. ArrayList:
    a. When the operation is to add data after a column of data rather than in the front or in the middle, and it is necessary to randomly access the elements, it is better to use ArrayList.
    b. ArrayList is the most commonly used List implementation class, which is implemented internally through an array, which allows fast random access to elements. The disadvantage of the array is that there can be no space between each element. When the size of the array is not sufficient, the storage capacity needs to be increased, and the data of the existing array must be copied to the new storage space. When inserting or deleting elements from the middle of the ArrayList, the array needs to be copied, moved, and the cost is relatively high. Therefore, it is suitable for random lookups and traversals, not for insertions and deletions.
    3. LinkedList:
    a. When adding or deleting operations to the front or middle of a column of data, and accessing the elements in sequence, use LinkedList.
    b. LinkedList uses a linked list structure to store data, which is very suitable for dynamic insertion and deletion of data, and the speed of random access and traversal is relatively slow. In addition, it also provides methods that are not defined in the List interface, which are specially used to operate the header and footer elements, which can be used as stacks, queues and bidirectional queues.

Vector and ArrayList are very similar in use, both can be used to represent a collection of a variable number of object applications, and the elements can be accessed randomly.

The difference between ArryList and LinkedList:
When dealing with a column of data items, Java provides two classes ArrayList and LinkedList. The internal implementation of ArrayList is based on the internal array Object[], so conceptually it is more like an array; however, the internal implementation of LinkedList It is based on a set of connected records, so it is more like a linked list structure; so they have a big difference in performance.
It can be seen from the above that when inserting data in front of or in the middle of ArrayList, all subsequent data must be moved back accordingly, which takes a lot of time; therefore, when the operation is to add data after a column of data instead of in ArrayList performance is better when you need to access the elements in the front or middle and need to access the elements randomly.
However, when accessing an element in the linked list, you must start from one end of the linked list and search element by element along the direction of the connection until the desired element is found. Therefore, when executing the front or middle of a column of data LinkedList is used when adding or removing operations, and when accessing its elements in order.
If in actual operation, the first two situations occur alternately, you can consider using a general interface such as List without caring about the specific implementation. In specific cases, its performance is guaranteed by the specific implementation.

  • HashTable, HashMap, HashSet:
    HashTable and HashMap use the same storage mechanism, with the following differences:
    1. HashMap:
    a. Entry objects composed of key-values ​​are stored in an array, with no capacity limit;
    b. Entry is searched based on key hash Where the object is stored in the array, the hash conflict is resolved by a linked list;
    c. When inserting elements, the capacity of the array may be expanded, and the hash needs to be recalculated when expanding the capacity, and the object is copied to the new array;
    d . is not thread-safe;
    e. Iterator is used for traversal;

    2. HashTable:
    a. It is thread-safe;
    b. Neither key nor value is allowed to have a null value; when the Put method is called in HashTable, if the key is null, a NullPointerException will be thrown directly;
    c. Traversal use is the Enumeration enumeration;

    3. HashSet:
    a. Based on HashMap implementation, no capacity limit;
    b. It is not thread-safe;
    c. It does not guarantee the order of data;

  • TreeSet, TreeMap:
    Both TreeSet and TreeMap are implemented completely based on Map, and neither support get(index) to obtain the element at the specified position, which needs to be traversed to obtain it. In addition, TreeSet also provides some sorting support, such as incoming Comparator implementation, descendingSet and descendingIterator.
    1. TreeSet:
    a. Based on TreeMap, it supports sorting;
    b. It is not thread-safe;

    2. TreeMap:
    a. A typical red-black tree-based Map implementation, so it requires a key comparison method, either passing in the Comparator comparator implementation, or the key object implementing the Comparator interface;
    b. It is not thread-safe;

  • StringBuffer and StringBulider:
    Both StringBuilder and StringBuffer inherit from the AbstractStringBuilder class, which also uses a character array to save strings in AbstractStringBuilder.

1. Comparison of execution speed: StringBuilder > StringBuffer;
2. StringBuffer and StringBuilder, they are string variables and changeable objects. Whenever we use them to operate on strings, it is actually on an object Operation, unlike String, creates some objects for operation, so the speed is faster;
3. StringBuilder: thread-unsafe;
4. StringBuffer: thread-safe;
 
summary of the use of String, StringBuffer and StringBulider:
1. If you want to operate a small amount of data, use = String
2. Single thread operation string buffer operation under large amount of data = StringBuilder
3. Multi-thread operation string buffer operation under large amount of data = StringBuffer

Reprinted from: https://blog.csdn.net/u011389474/article/details/54602812

Guess you like

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