背景:
不管是做Java开发、C开发、IOS开发还是Android开发,都会遇到多线程开发的需求场景。那么问题就来了,多线程开发时无法避免的就要考虑线程安全和线程通信的问题。今天我们主要讲讲线程安全问题,Android中可能大家用synchronized关键字用多了、久了就对锁的概念缺乏了认知,所以这里就简单回顾补充一下这方面知识。
一、线程并发访问的问题
程序运行时JVM会将我们的内存分成线程私有和线程公有两大块,这个在之前的内存优化篇章里面也有详细的介绍过,这里就不再啰嗦了。那么当多个线程访问并操作修改公有内存中的同一个变量时就会出现冲突的情况(这就是多线程并发访问的问题)。而Android中我们常用的两种解决方式就是synchronized和ThreadLocal,当然了,解决这个问题的方案还有很多,这里只是通关这两个来引申一下锁和变量副本的概念。
synchronized:是利用锁的机制,使变量或代码块在某一个时刻只能有一个线程访问。
ThreadLocal:是为每一个线程提供了变量的副本,使得每个线程在某一个时刻访问到的都是自身的变量副本(即副本只供自身使用,线程数据私有化),但是这样就隔离了多个线程对同一个公有内存变量的数据共享。
这里要简单讲一下ThreadLocal是如何保证线程数据私有化的。这要从它的get/set方法说起
通过源码很清楚的看到,ThreadLocal在set或者get的过程中都是通过当前线程的ThreadLocalMap变量来存取数据的。而这个ThreadLocalMap就是个Key/Value的Map数据结构,只不过它和普通Map较大区别就是它的Key只能是ThreadLocal对象。这就奠定了Thread与ThreadLocal的绑定关系,当有数据存取操作时只会在当前线程的ThreadLocalMap(线程私有空间)中进行,从而实现了线程之前数据的隔离和确保线程数据的私有化。