Java锁
1. 多个线程: 当然得在多线程环境下。
2. 共享变量: 若不存在共享变量(即存在本地变量),多个线程只能访问本地线程栈的数据。
3. 可变变量: 即使存在共享变量,但是该变量不可变(即初始化后,就不会更新状态)。
4. 写操作: 即使共享变量可变,但是多个线程不存在更新操作(仅读操作),此时依然是线程安全的。

2. 共享变量: 若不存在共享变量(即存在本地变量),多个线程只能访问本地线程栈的数据。
3. 可变变量: 即使存在共享变量,但是该变量不可变(即初始化后,就不会更新状态)。
4. 写操作: 即使共享变量可变,但是多个线程不存在更新操作(仅读操作),此时依然是线程安全的。
为什么有了上述条件成立后,就有可能出现并发问题
归根结底,还是由于Java内存模型和硬件架构引起的,摘得一张好图,共赏之:
类似这种情形,跑在CPU上的一个线程将这个共享对象读到CPU缓存中,然后修改了这个对象。只要CPU缓存没有被刷新会主存,对象修改后的版本对跑在其它CPU上的线程都是不可见的。这种方式可能导致每个线程拥有这个共享对象的私有拷贝,每个拷贝停留在不同的CPU缓存中。
而Java中volatile的作用就是,让线程从主内存中读取变量,当这个变量被修改时,总会被写会到主内存中,这样就能保证多个线程能看到共享变量最新的值了(Java同步块(synchronized)也能达到同样的效果)。Java锁
锁在并发中,无疑是基础而直观重要的组件,是避免并发问题的好帮手。Java内置锁(synchronized)
Java内置的同步块(synchronized)就是最简单的锁工具,并且并发大师Doug Lea也建议,在synchronized能满足并发程序需求时,尽量就使用它,因为它足够简单明了,大部分开发人员都知道该关键字的用意,并且其性能问题,有可能随JVM优化而得到提升,其基本用法synchronized (sharedObj){ // 临界区