线程同步:
synchronized:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,作用的对象是调用这个 括起来的代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象
3. 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象
4. 修饰一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象
Synchronized的语义底层是通过一个 的语义底层是通过一个monitor的对象来完成,
其实wait/notify等方法也依赖于monitor对象,
这就是为什么 只有在同步的块或者方法中才能调用 只有在同步的块或者方法中才能调用wait/notify等方法,
否则会抛出 等方法,否则会抛出java.lang.IllegalMonitorStateException的异常。
每个对象有一个监视器锁(monitor)
当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获 指令时尝试获取monitor的所有权
1. 如果 如果monitor的进入数为 的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者
2. 如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1
3. 如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor 的所有权
1. 原子性 操作结果一致,比如转账
2. 可见性 共享变量得一致,比如缓存
3. 顺序性 每次执行代码的先后顺序一致,比如代码从上到下执行,别多个线程瞎tm乱跳跃