synchronized的使用
public class Demo {
private static int count=0;
public static void inc(){
synchronized (Demo.class){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
public static void main(String[] args) throws InterruptedException {
for (int i=0;i<1000;i++){
new Thread(()->{
Demo.inc();
}).start();
}
Thread.sleep(3000);
System.out.println("运行结果:"+count);
}
}
运行结果:1000
synchronized的三种应用方式
synchronized有三种方式来加锁,分别是
synchronzied括号后面的对象
synchronized的字节码指令
synchronized的锁的原理
Java对象头
Mark Word
在源码中的体现
如果想更深入了解对象头在JVM源码中的定义,需要关心几个文件,oop.hpp/markOop.hpp oop.hpp,每个 Java Object 在 JVM 内部都有一个 native 的 C++ 对象 oop/oopDesc 与之对应。先在oop.hpp中看 oopDesc的定义
_mark 被声明在 oopDesc 类的顶部,所以这个 _mark 可以认为是一个 头部, 前面我们讲过头部保存了一些重要的 状态和标识信息,在markOop.hpp文件中有一些注释说明markOop的内存布局
Monitor
synchronized的锁升级和获取过程
自旋锁(CAS)
偏向锁
轻量级锁
重量级锁
wait和notify
wait和notify是用来让线程进入等待状态以及使得线程唤醒的两个操作
public class ThreadWait extends Thread {
private Object lock;
public ThreadWait(Object lock){
this.lock=lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("开始执行 thread wait....");
try {
lock.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("执行结束 thread wait....");
}
}
}
public class ThreadWait extends Thread {
private Object lock;
public ThreadWait(Object lock){
this.lock=lock;
}
@Override
public void run() {
synchronized (lock){
System.out.println("开始执行 thread wait....");
lock.notify();
System.out.println("执行结束 thread wait....");
}
}
}
wait和notify的原理
wait和notify为什么需要在synchronized里面