Java-HIT

2019/06/07 Java

synchronized

Q0:锁得是什么

public class SyncTest{
    public synchronized void methodA(){
    }
    public void methodB(){
            synchronized(this){
        }
    }
    public void methodC(){
            synchronized(xxx.class){
        }
    }
    public static synchronized methodD(){
    }
}

前两种锁的是实例对象,即对象锁,后两种锁的是类对象,即类锁(类锁只是个概念,因为本质锁的本质还是对象)
 
结论:
1.持有的是同一个实例,是能够达到锁住资源,不让别的线程进入的目的的。就算访问的不是相同的代码块,也会等待。两个线程持有的是同一个syncTest对象,一个执行syncTest.methodA(),另一个执行syncTest.methodB(),也会有锁的效果。
2.但是如果大家都是new SyncTest()的话,即使访问同一段代码,是锁不住的!!!!!!!因为大家所持的实例对象不一样!!!!
3.后两种的话,无论是用类直接调用,还是实例调用,无论是否同一个实例,都会互斥。
4.对象锁和类锁,相互不影响
 

Q1:是否是可重入的

可重入
扩展 可重入锁:
        https://zh.wikipedia.org/wiki/%E5%8F%AF%E9%87%8D%E5%85%A5
        https://www.cnblogs.com/incognitor/p/9894604.html

        当线程请求一个由其它线程持有的对象锁时,该线程会阻塞,而当线程请求由自己持有的对象锁时,如果该锁是重入锁,请求就会成功,否则阻塞。
        
重入锁实现可重入性原理或机制是:
        每一个锁关联一个线程持有者和计数器,当计数器为 0 时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;当某一线程请求成功后,JVM会记下锁的持有线程,并且将计数器置为 1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为 0,则释放该锁。

Search

    Table of Contents