JDK的ThreadLocal理解(一)使用和测试
? ? ? ?ThreadLocal是java中轻量级的线程同步解决方法,为了达到线程安全的目的,采用的是空间隔离的方法。使用方式如下:
?
1、定义2个会被多线程共享的bean,一个使用ThreadLocal,一个不使用任何线程同步措施
package bean;public interface IShareBean { public void get(); public void autoInc();}package bean.impl;import bean.IShareBean;public class SafeShareBeanImpl implements IShareBean{// 创建一个线程局部变量并赋初值// 该变量是被所有访问SafeShareBeanImpl类的线程共享的,但不存在线程安全问题private static ThreadLocal<Integer> localCount = new ThreadLocal<Integer>(){protected Integer initialValue() {return 0;};};public void get() {System.out.println(Thread.currentThread().getName()+ ",after increment:" + localCount.get());}public void autoInc() {int count = localCount.get();System.out.println(Thread.currentThread().getName()+ ",before increment:" + count);count++;localCount.set(count);}}package bean.impl;import bean.IShareBean;public class UnSafeShareBeanImpl implements IShareBean{private int count = 0;public void get() {System.out.println(Thread.currentThread().getName()+ ",after increment:" + count);}public void autoInc() {System.out.println(Thread.currentThread().getName()+ ",before increment:" + count);count++;}}?
2、定义一个线程实现类,用来访问共享bean中的方法
package thread;import bean.IShareBean;public class ThreadBody implements Runnable{private IShareBean bean = null;public ThreadBody(IShareBean bean) {this.bean = bean;}@Overridepublic void run() {bean.autoInc();try {Thread.sleep(1000);} catch (InterruptedException e){e.printStackTrace();}bean.get();}}?
3、测试线程安全
import thread.ThreadBody;import bean.IShareBean;import bean.impl.SafeShareBeanImpl;import bean.impl.UnSafeShareBeanImpl;public class Client {public static void main(String[] args) {//会被线程共享的对象IShareBean unsafe = new UnSafeShareBeanImpl();IShareBean safe = new SafeShareBeanImpl();// 线程1和2,共享unsafeThread one = buildThread("unsafe-thread-1", unsafe);Thread two = buildThread("unsafe-thread-2", unsafe);// 线程安全3和4,共享safeThread three = buildThread("safe-thread-1", safe);Thread four = buildThread("safe-thread-2", safe);three.start();four.start();one.start();two.start();}public static Thread buildThread(String name, IShareBean bean) {ThreadBody body = new ThreadBody(bean);Thread thread = new Thread(body);thread.setName(name);return thread;}}?
运行以上代码可以发现,使用ThreadLocal,的确以一种很优雅的方式解决了线程安全问题。
?
?
?
??
1 楼 zh_harry 14 小时前 ThreadLocal独家解秘 附JDK源码