Detailed use ThreadLocal

ThreadLocal Profile

ThreadLocalMainly to solve the multi-threaded concurrent access to data led to inconsistencies. ThreadLocalEach thread uses this variable are provided a copy of the value of a variable, although the cost of memory in this way, but greatly reducing the thread synchronization performance caused by consumption, but also reduces the complexity of thread concurrency control.

For example: the ThreadLocalmetaphor box data store, the box can only store owner's private data cartridge. Since the data space is isolated, so multi-threaded concurrent access and independently of each other, thus avoiding thread-safety issues.

How do ThreadLocal is to maintain a copy of each thread variables? In fact, the idea is very simple to achieve, in ThreadLocala class ThreadLocalMapfor a copy of each thread of variable storage.

The difference between ### ThreadLocal and Synchonized

  1. ThreadLocal: Using a copy of the mechanism, so that each thread object at a time of the visit to be different, so as to ensure inter-thread data isolation .
  2. synchronized: Use the lock mechanism, so that objects can only be one thread access at a time, so as to ensure inter-thread data sharing .

The sample code

import java.util.*;

public class ThreadLocalDemo implements Runnable {

    // list 不是线程安全的,所以每个线程都要有自己独立的副本
    private static ThreadLocal<List> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) throws InterruptedException {
        ThreadLocalDemo obj = new ThreadLocalDemo();
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(obj, "thread" + i);
            Thread.sleep(1000);
            t.start();
        }
    }

    @Override
    public void run() {
        List<String> list = new ArrayList<>();
        list.add(Thread.currentThread().getName());
        threadLocal.set(list);
        System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get());
        list.add("1");
        list.add("2");
        System.out.println(Thread.currentThread().getName() + ":" + threadLocal.get());
    }

}
复制代码

ThreadLocal source

  1. ThreadLocal class get()method
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
复制代码

Which ThreadLocalMapmay be understood as customized HashMap, but ThreadLocalonly for its packaging, and the value of the variable pass, by ThreadLocalMapthe get()method to get the value of the current thread local variables.

  1. ThreadLocal class set()method
public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
复制代码

The principle and get()method as the internal ThreadLocalMapmanagement of data, when set to check whether the map is empty, if not empty directly save the data, if you create an empty map and then save the data.

ThreadLocal memory leaks

ThreadLocalMapKey is used as a weak referenced strong reference value. So, if ThreadLocalthere is no strong case to be cited under the outside, at the time of execution GC will clean out the key, and the value will not be cleared. As a result, ThreadLocalMapthe key will be to null Entry. If not, then any measure, value may never be recovered GC, this time may cause a memory leak.

Above, ThreadLocalMapthe implementation has been taken into account in the call set(), get()and remove()when the process will clean up key to null records. (After we finished using ThreadLocal, preferably manually call remove () method)

Weak references

If an object has only a weak reference, it belongs to the dispensable object. Weak and soft references cited difference is that: only a weak reference objects have more short life cycle. Garbage collector thread scans the memory area under its jurisdiction when executed, once the object has only weak references found, regardless of the current memory space is sufficient or not, it will be recycled. However, because the garbage payback period is a low priority thread, therefore we are not necessarily those objects will soon find only a weak reference.

Weak references can be a reference queue ( ReferenceQueue) used in combination, if the weak reference object is garbage, Java virtual machine will be added to this weak reference references associated with the queue.

Guess you like

Origin juejin.im/post/5d1e9fa251882552903ca97c