非线程安全:多个线程对同一个对象中实例变量进行并发访问 发生的后果就是脏读 也就是取到的数据其实被更改过的
线程安全:获取的实例变量经过同步处理 不会出现脏读现象
sychronized关键字:
关键字synchronized取得的锁都是对象锁 哪个线程先执行带synchronized关键字的方法 哪个线程就持有该方法所属对象的锁Lock 那么其他线程只能等待 前提是多个线程访问的是同一个对象
如果多个线程访问多个对象 JVM会创建多个锁
只有共享资源的读写访问才需要同步化 不是共享资源没有必要同步
synchronized锁重入:
synchronized同步语句块:
Java还支持任意对象作为对象监视器来实现同步的功能 这个任意对象大多数是实例变量及方法的参数
使用格式 synchronized(非this对象x)
多个线程调用同一个方法是随机的
静态同步synchronized方法与synchronized(class)代码块:
String常量池的影响:
如果String的两个值相等 两个线程会持有相同的锁 因此在大多数情况下 同步synchronized代码块都不使用String作为锁对象
而用其他 比如new Object()实例化一个Object对象 但它并不放入缓存中
多线程的死锁:
不同的线程在等待根本不可能被释放的锁 从而导致所有的任务都无法继续完成 死锁不可避免 会造成线程的假死
使用JDK自带的工具来监测是否有死锁的现象 jps jstack命令
关键字synchronized的知识点还涉及内置类的使用:
内部类:
使用内部类:
Java8改进的匿名内部类:
内置类与静态内置类:
持有不同的锁
volatile关键字:
volatile关键字的作用使变量在多个线程间可见
volatile特性:
具备可见性 不具备同步性 也就不具备原子性
使用原子类:
原子操作是不能分割的整体 没有其他线程能够中断或检查正在原子操作中的变量
一个原子类型 就是一个原子操作可用的类型 它可以在没有锁的情况下做到线程安全