关于java并发安全的几个常用关键字的讲解,只是说明几个我们熟悉的关键字,不是并发包中的集合和锁,并发集合和锁会在后面的文章中进行讲解。
关于java并发安全的关键字主要有:final,volatile,synchronized
final:Java中,定义为final的字段只初始化一次,在正常情况下将不能再被改变(利用反射可以改变final字段的值)。定义为final的类是禁止被子类集成的,保证该给的唯一和安全。还有一个需要重点讲解的,final定义的集合是不可变的集合,但是集合中的引用是可变的,举例:final Map map = new HashMap(); 该map是不可变的,假设我们的map.put("key1","test1")中,我们是可以修改map.put("key1","test_1")的。我们要区分final关键字的内容及对象,但是可以保证final修改的对象是线程安全的。
volatile:用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。简单点说,被volatile修改的变量,你每次读取该变量的值时需要从主内存中去重新加载一次,或者说修改该变量的线程修改该变量后,该变量被volatile修改,就是告知java虚拟机,需要用到该变量是需要其他线程重新加载该变量,但是volatile关键是不能保证原子性,它保证是可见性。举个例子,两个线程同时修改volatile a = 0的时候,同时操作,此时是不能保证原子性的。
synchronized:锁关键字,这个是最常用的线程安全关键字。被synchronized修改的方法或者代码块,是保证线程安全的,在多线程环境中,是保证一次只能有一个线程进入该方法或者代码块,保证线程的安全。
线程安全涉及到java内存的一些内容,这说明下java中的主内存和线程内容之间的操作关系。
主内存 线程内存(执行顺序从上至下)
变量num -------> read(读)
load
use
asign
store
<------- write(写)
上面的简单示意图说明了线程的操作内容和java主内存的关系,如果线程安全的话,每次线程的操作都将和主内容进行同步操作,保证数据的安全。如果多线程访问没有锁或者线程安全的话,每个线程有自己的内存副本,会导致和java主内存有冲突,不能保证数据的一致性。