synchronized 关键字
synchronized 的作用
synchronized 可以保证被它修饰的方法或代码块在任意时刻只能有一个线程执行。
synchronized 和 volatile 的区别是什么?
volatile 解决的是内存可见性问题,会使得所有对 volatile 变量的读写都直接写入主存,即 保证了变量的可见性。
synchronized 解决的是执行控制的问题,它会阻止其他线程获取当前对象的监控锁。
synchronized 使用
对当前实例对象加锁
下面的两个方法 等效
public synchronized void test(){
}
public void test1(){
synchronized (this){
}
}
对这个类的所有对象加锁
下面的两个方法等效
public synchronized static void test2(){
}
public static void test3(){
synchronized (SynchronizedClient.class){
}
}
说一下 synchronized 底层实现原理?
synchronized 同步代码块的实现是通过 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。当执行 monitorenter 指令时,线程试图获取锁也就是获取 monitor(monitor对象存在于每个Java对象的对象头中,synchronized 锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因) 的持有权。
其内部包含一个计数器,当计数器为 0 则可以成功获取,获取后将锁计数器设为 1 也就是加 1。相应的在执行 monitorexit 指令后,将锁计数器设为 0,表明锁被释放。如果获取对象锁失败,那当前线程就要阻塞等待,直到锁被另外一个线程释放为止