上篇讲到多线程线程安全问题的解决思路,这篇将详细讲解资源隔离ThreadLocal的实践。
ThreadLocal也叫线程局部变量,类似Map结构,以当前线程为key。既然是以资源隔离的思想保证线程安全,那么保存到每个线程的对象就应该是一个副本,切记这样的对象不能是单例,如果非要使用单例创建对象,保存到每个线程的必须是单例对象的克隆对象。
![](https://upload-images.jianshu.io/upload_images/6759284-fcbe7c2cbb48227c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/q/50)
图片发自简书App
下面演示一个实例来实践ThreadLocal:
![](https://upload-images.jianshu.io/upload_images/6759284-b008520eb05a5d25.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/q/50)
图片发自简书App
![](https://upload-images.jianshu.io/upload_images/6759284-fbda24045db7a6cd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/q/50)
图片发自简书App
![](https://upload-images.jianshu.io/upload_images/6759284-d80ef82439c4c589.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/q/50)
图片发自简书App
![](https://upload-images.jianshu.io/upload_images/6759284-6a96a83f37bb4aa8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1080/q/50)
图片发自简书App
通过这个实践,可以看到,使用ThreadLocal使各个线程拥有对象的副本,各个线程对副本的修改不会影响到别的线程的副本,从而避免了线程安全问题。
再次强调,使用单例创建的对象,保存到ThreadLocal,一定要克隆对象。对象其实就是索引,单例,只有一个对象,一个索引,多线程操作依然有线程安全问题,数据会被篡改。切记切记。