ThreadLocal and strong weak virtual reference in multithreaded learning note 5

Keywords: jvm Spring Java

ThreadLocal

There is a Map in ThreadLocal, which maintains a copy for each thread to ensure that the data in each thread is isolated. Let's look at a small program

public class ThreadLocalDemo {

    static Person p = new Person();

    public static void main(String[] args) {

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(p.name);
        },"t1").start();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            p.name = "Mary";
        },"t2").start();
    }


    static class Person {

        public String name = "Jack";
    }
}

The printing result is Mary. In fact, the result I want is Jack. I don't want the change of variables in t2 thread to affect the result of p1 thread. Therefore, ThreadLocal is needed to isolate the thread

public class ThreadLocalDemo2 {

    static ThreadLocal<Person> t = new ThreadLocal<>();

    public static void main(String[] args) {
        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(t.get());
        },"t1").start();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Person person = new Person();
            person.name = "Mary";
            t.set(person);
        },"t2").start();

    }

    static class Person {
        public String name = "Jack";
    }
}

The execution result of this code is null. If people who don't know it will be curious, it is clear that Mary is set in t2 below. Why t1 gets null is because ThreadLocal isolates the thread

  • Usage scenario of ThreadLocal
    Spring declarative transaction ensures that the data connection is the same connection

Strong citation

The instance created by the strong reference new keyword, or the object created by Class.newInstance(), is a strong reference. The strong reference will be recycled by the garbage collector only when the reference is set to null. The code is as follows

public class NormalReferenceDemo {
    public static void main(String[] args) throws IOException {
        M m = new M();
        m = null;
        System.gc(); //DisableExplicitGC

        System.in.read();
    }
}

SoftReference

The soft reference will be recycled by the garbage collector only when the memory is not enough. The code is as follows

public class SoftReferenceDemo {
    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
        //m = null;
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());

        //Allocate another array, and the heap will not fit. At this time, the system will garbage collect. First, recycle it once. If it is not enough, it will kill the soft reference
        byte[] b = new byte[1024 * 1024 * 15];
        System.out.println(m.get());
    }
}

WeakReference

The weak reference object pointed by the weak reference. If there is a strong reference to the reference object, once the strong reference is not available, the object will be recycled immediately when garbage collection. Use the scene "container" (ThreadLocal source code). The weak reference is simple to use the code

public class WeakReferenceDemo {
    public static void main(String[] args) {
        WeakReference<M> m = new WeakReference<>(new M());

        System.out.println(m.get());
        System.gc();
        System.out.println(m.get());


        ThreadLocal<M> tl = new ThreadLocal<>();
        tl.set(new M());
        tl.remove();
    }
}

This is how the ThreadLocal is executed internally, as shown in the following figure

Virtual reference

  • Virtual reference management out of heap memory

Easy to use code

public class PhantomReferenceDemo {
    private static final List<Object> LIST = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();



    public static void main(String[] args) {


        PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);


        new Thread(() -> {
            while (true) {
                LIST.add(new byte[1024 * 1024]);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                System.out.println(phantomReference.get());
            }
        }).start();

        new Thread(() -> {
            while (true) {
                Reference<? extends M> poll = QUEUE.poll();
                if (poll != null) {
                    System.out.println("--- Virtual reference objects are jvm Recovered ---- " + poll);
                }
            }
        }).start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

The execution result is shown in the figure:

We found that the fetching is null, because the virtual reference will be loaded into the Queue when it is recycled, but we can't get the object that the virtual reference points to by ourselves, because this memory doesn't belong to the heap memory in the JVM, but directly opens up the out of heap memory. We can't get the object in the out of heap memory through java. See the following figure

Published 19 original articles, won praise 1, and visited 397
Private letter follow

Posted by Helaman on Tue, 21 Jan 2020 03:26:22 -0800