How does a HashSet guarantee non-duplicate data

HashSet constructor
public HashSet(a) {
        map = new HashMap<>();
    }
// Instantiate a map using HashMap
Copy the code

add()

  public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
// It treats the passed object as a HashMap key. Since a HashMap key is not allowed to duplicate, every time a duplicate value is passed into the HashSet, the value will be overwritten, and the key will not be affected, thus ensuring that there is no duplicate data in the HashSet
Copy the code

How does LinkedHashMap keep data organized

HashMap is an unordered map, based on the need for sorting scenarios, the JDK introduced a underlying implementation of HashMap, consisting of a bidirectional linked list.

Sorting methods:

  • Depending on the order of writing
  • According to the order of access
   /** * The head of the doubly linked list. */
    private transient Entry<K,V> header;

    /**
     * The iteration ordering method for this linked hash map: <tt>true</tt>
     * for access-order, <tt>false</tt> for insertion-order.
     *
     * @serial* /
    private final boolean accessOrder;
    
    private static class Entry<K.V> extends HashMap.Entry<K.V> {
        // These fields comprise the doubly linked list used for iteration.
        Entry<K,V> before, after;

        Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
            super(hash, key, value, next); }}Copy the code

Principle of synchronized keyword

Synchronized is a common solution to concurrency problems and can be used in the following three ways:

  • Synchronized normal methods lock the current object.
  • Synchronized static methods that lock the current Class object.
  • Synchronized blocks that lock objects in ().

Realize the principle of

The JVM synchronizes methods and synchronized blocks by entering and exiting the object Monitor.

The implementation is to add a monitor.enter directive after compilation before synchronous method calls, and insert monitor.exit directives at exit methods and exceptions.

Its essence is to fetch an object Monitor, and the fetch process is exclusive so that only one thread can access it at a time.

Threads that do not acquire the lock will block at the method entry until the thread that acquired the lock, monitor.exit, attempts to acquire the lock.

Common Problems with multithreading

Context switch

Multithreading does not have to be supported on a multi-core processor, even a single core processor can support multithreading. The CPU allocates a certain time slice to each thread. Because the time is very short, usually dozens of milliseconds, the CPU can keep switching threads to perform tasks so as to achieve the effect of multi-threading.

However, since the thread needs to save the information of the current execution during the switch (see details), the process of the thread being deprived of the time slice by the CPU and then running again to recover the information saved last time is called context switch.

Context switching is very efficient.

There are usually the following solutions:

  • Use lock-free programming, such as Hash(ID) segmentation of data, and each thread processes its own segmentation of data, thus avoiding the use of locks.
  • Use CAS(Compare and Swap) algorithm, such as Atomic package using CAS algorithm (see details).
  • Create thread properly, avoid creating a few threads but most of them are waiting because every time you switch from waiting to RUNNING is a context switch.

A deadlock

Deadlock scenarios typically involve threads A and B both waiting for each other to release the lock, or one of the threads releasing the lock has an exception such as an infinite loop. This will cause the system to become unavailable.

Common solutions are as follows:

  • Try to acquire only one lock per thread.
  • A thread occupies only one resource.
  • Try using a timing lock to at least guarantee that the lock will be released eventually.

Resource constraints

When the bandwidth is limited, one thread needs 1M/S to download a resource. When 10 threads are open, the speed is not multiplied by 10 times, but it will increase the time, because the context switch is time-consuming.

If resources are limited, tasks can be clustered, with different machines handling different data, similar to the lockless programming mentioned at the beginning.

The article has helped you, please pay attention to the wechat public number: wanton dissociation has more wonderful waiting for you