并发中的可见性和同步

共享变量的可见性和同步

        你必须明白像Java这种通过改变共享变量状态来进行多线程间通信的语言,并发的核心是共享变量的可见性,这个可见性并不是想象中那么好维护,C语言家族(包括C/C++/Java等,ps:实现层使用的是面向过程)给出的解决方案是同步变量状态。首先,我们必须明白为什么存在变量可见性?在java提供的多线程与锁模型里,内存不是一整块,分为主内存和各个线程的本地缓存,使用start函数创建线程时,会为线程分配一定的内存空间,这时会从主内存读取共享变量(read操作),存在本地缓存里。例如,有2个线程:threadA和threadB,同时初始化(多核处理器),同时读到主内存中的共享变量 a=1;,threadA与threadB彼此都是互相隔离的、彼此近似透明的,threadA是不知道还有其他线程对a进行读写操作的,一旦a的状态改变了,其他处理器中的线程是不知道a的状态已经改变了的,所以,必须想办法告知其他线程,a的状态已经改变,并且,这种通知应该是在其他线程使用a之前就完成的,不然,a的状态就被污染了,比如threadA和threadB是并发地递增a的值,那么任何线程对a的操作必须对其他线程的后续操作是可见的,什么意思?就是threadA将a加1,a变为2,此时threadB再对a加1,在进行加法操作前,threadB缓存中的a的值必须刷新为2,而不是保持为1。这种跨处理器的操作(ps:对单核使用多线程,线程切换反而会降低性能)不能自发地在处理器之间可见,需要设计一种机制保证这种可见性可以无视处理器的分割,使改变共享变量的状态的操作就像各处理器直接在主内存进行一样,这种机制就是同步。

所谓同步,是在使用共享变量时,放弃共享变量的旧状态,获取共享变量的新状态。至于加不加锁,无所谓,你要保证你用到的变量状态是最新鲜的就可以了。

你可能感兴趣的:(并发中的可见性和同步)