• ThreadLocal模式


    线程封闭#

    当访问共享的可变数据时,通常需要同步.一种避免同步的方法就是不共享数据.如果仅在单线程内访问数据,就不需要同步.这种技术被称为线程封闭,它是实现线程安全性的最简单方式之一.当某个对象封闭在一个线程中,这种用法将自动实现线程安全性,即使被封闭的对象本身不是线程安全的.

    ThreadLocal类##

    • jdk实现的ThreadLocal是典型的维持线程封闭性的方法,这个类能使线程中的某个值与保存的对象关联起来.ThreadLocal提供了set和get等访问接口和方法,这些方法为每个使用这个变量的线程都存有一份独立的副本.
    • ThreadLocal对象通常用于防止对可变的单实例变量或全局变量进行共享.

    一个小例子来使用ThreadLocal类

    public class Counter {
    private static ThreadLocal<Integer> context = new ThreadLocal<Integer>() {
    	protected  Integer initialValue() {
    		return 10;
    	}
    };
    
    public static Integer get() {
    	return context.get();
    }
    
    
    public static void set(Integer value) {
    	context.set(value);
    }
    
    public static Integer getNextCounter() {
    	context.set(context.get()+1);
    	return context.get();
    }
    

    }

    创建多个线程访问ThreadLocal类初始化的变量.

    public class ThreadLocalTest extends Thread{
    
    public void run() {
    	for (int i = 0; i < 3; i++) {
    		System.out.println("Thread["+Thread.currentThread().getName()+"],counter="
    				+Counter.getNextCounter());
    	}
    }
    
    
    public static void main(String[] args) {
    	ThreadLocalTest thread1 = new ThreadLocalTest();
    	ThreadLocalTest thread2 = new ThreadLocalTest();
    	ThreadLocalTest thread3 = new ThreadLocalTest();
    	thread1.start();
    	thread2.start();
    	thread3.start();
    }
    

    }

    3个线程对初始值的修改都互不影响

    Thread[Thread-1],counter=11
    Thread[Thread-1],counter=12
    Thread[Thread-1],counter=13
    Thread[Thread-2],counter=11
    Thread[Thread-2],counter=12
    Thread[Thread-2],counter=13
    Thread[Thread-0],counter=11
    Thread[Thread-0],counter=12
    Thread[Thread-0],counter=13
    

    get和set方法是如何与当前线程关联起来的?##

    public class ThreadLocal<T> {
    
        public void set(T value) {
            Thread t = Thread.currentThread();//获取当前访问的线程
            ThreadLocalMap map = getMap(t);//获取当前线程中的ThreadLocalMap
            if (map != null)
                map.set(this, value);//如果不为空的话,就以当前hreadLocal实例为key,存储的对象为值存入ThreadLocalMap 中
            else
                createMap(t, value);//创建一个ThreadLocalMap 
        }
    
            void createMap(Thread t, T firstValue) {
            t.threadLocals = new ThreadLocalMap(this, firstValue);//同样以当前ThreadLocal实例为key
        }
    
    
        public T get() {
            Thread t = Thread.currentThread();//获取当前访问的线程
            ThreadLocalMap map = getMap(t);//获取当前线程中的ThreadLocalMap
            if (map != null) {
                ThreadLocalMap.Entry e = map.getEntry(this);//获取当前线程中以当前ThreadLocal实例为key的变量值
                if (e != null)
                    return (T)e.value;
            }    
            return setInitialValue();//当map不存在的时候设置初始值.
        }
    
            ThreadLocalMap getMap(Thread t) {//从线程中获取对应的ThreadLocalMap,是多个ThreadLocal的集合.
            return t.threadLocals;
        }
    
    
    }
  • 相关阅读:
    读书笔记《七天学会NodeJS》(5)
    读书笔记《七天学会NodeJS》(4)
    读书笔记《七天学会NodeJS》(3)
    读书笔记《七天学会NodeJS》(2)
    读书笔记《七天学会NodeJS》(1)
    读书笔记《七天学会NodeJS》(0)
    读书笔记《Node.JS开发指南》
    JavaScript比较特殊的一些概念(三)
    JavaScript比较特殊的一些概念(二)
    JavaScript比较特殊的一些概念(一)
  • 原文地址:https://www.cnblogs.com/itsrobin/p/5180581.html
Copyright © 2020-2023  润新知