线程安全也不是指线程的安全,而是指内存的安全。为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的进程,这是由操作系统保障的
每个进程的内存空间中都会有一块特殊的公共区域,通常称为堆(内存)。进程内所有的线程都可以访问到该区域-------原因
在堆内存中的数据由于可以被任何线程访问到,在没有限制的情况下存在被意外修改的风险! ----所以说堆内存在没有保护机制下,对于多线程来说是不安全的地方---如下解决方案:
方案一:(基于位置确保安全)----局部变量是安全但是使用范围受限---把东西藏到自己的私有地方
在程序中,操作系统会给每个线程分配一个属于自己的内存空间----栈内存!(其他线程无法访问)
----如果一些数据只有某个线程使用,其他线程不能操作且不需要操作,这些数据就可以放入线程的栈内存中(例如:局部变量)
----局部变量会在每个线程的栈内存中都分配一份。由于线程的栈内存只有自己可以访问,所以栈中存的变量只属于自己,其他线程访问不到
方案二:(放在公共区域)----成员变量---每人复制一份,各玩各的,互不影响
每个线程可以拷贝一份,只处理自己的那一份,而不去影响其他线程,这不就安全了吗!---------ThreadLocal类----其中的数据是分配在公共区域的堆内存中的
每个线程运行时,都会拷贝一份存储到自己的本地(例如共享单车(可以copy)是数据,我你他是线程)
方案三:final修饰-----只能看不能摸
方案四:互斥锁--为了确保安全,每次先获取锁,操作完后再释放锁
方案五:CAS(Compare And Swap)-------地广人稀的情况----并发很小的情况下(乐观锁)-----ABA---加版本号,内容被修改一次就加一
总结:前两种属于隔离法,一个是位置隔离,一个是数据隔离
之后两种是标记法,一个只读标记,一个加锁标记
最后一个大胆法,先来试一下,不行再重头开始