原子性:
原子性就是指该操作是不可再分的。不论是多核还是单核,具备原子性的量,同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性。比方 a = 1;
非原子性:
也就是整个过程中会呈现线程调度器中断操作的景象
相似 ”a ++” 这样的操作不具备原子性,因为它可能要通过以下两个步骤:
(1)取出 a 的值
(2)计算 a+1
如果有两个线程 t1,t2 在进行这样的操作。t1 在第一步做完之后还没来得及加 1 操作就被线程调度器中断了,于是 t2 开始执行,t2 执行结束后 t1 开始执行第二步(此时 t1 中 a 的值可能还是旧值,不是肯定的,只有线程 t2 中 a 的值没有及时更新到 t1 中才会呈现)。这个时候就呈现了谬误,t2 的操作相当于被忽略了
相似于 a += 1 这样的操作都不具备原子性。还有一种非凡状况,就是 long 跟 double 类型某些状况也不具备原子性,具体可参考:java 中 long 和 double 类型操作的非原子性探索
共享变量:
如果一个变量在多个线程的工作内存中都存在正本,那么这个变量就是这个几个线程的共享变量
可见性:
一个线程对共享变量值的批改,可能及时的被其它线程看到。
在多线程的状况下,共享变量不肯定是可见的。要想实现变量的肯定可见,能够应用 synchronized
、volatile
两种形式(其实还有final
,然而它初始化后,值不可 更改,所以个别不必它实现可见性)。具体做法可参考:synchronized 实现可见性、volatile 个性
Java 内存模型 (Java Memory Model) 形容了 Java 程序各种变量( 线程共享变量 ) 的拜访规定,以及在 JVM 中将变量存储到内存和从内存中读取出变量这样的底层细节。
在 Java 内存模型 (以下简称为 JMM) 中:
1)所有的变量都存储在主内存中
2)每个线程都有本人独立的工作内存,外面保留该线程应用到的变量的正本(主内存中该变量的一份拷贝)
用上面的图能够直观的看到 JMM 中,线程、工作内存、主内存之间的关系:
在下面的图中,能够看到线程只与工作内存交互,不能间接拜访主内存。当主内存中有一个共享变量 X,则工作内存则是将 X 拷贝,而后线程是操作工作内存中 X 的正本
在 JMM 中,有两条规定:
1)线程对共享变量的所有操作都必须在本人的工作内存中进行,不能间接从主内存中读写
2)不同线程之间无法访问其余线程工作内存中的变量,线程间变量值的传递须要通过主内存来实现
共享变量要实现可见性,必须通过如下两个步骤:
1)把工作内存 1 中更新过的共享变量刷新到主内存中
2)把主内存中最新的共享变量的值更新到工作内存 2 中
援用: https://www.cnblogs.com/xuwen…