synchronized锁

基础知识:
synchronized锁可分为对象锁和类锁, 顾名思义对象锁就是给实例对象进行加锁, 类锁则是给类进行加锁

synchronized常见方式如下:

1 对象方法加锁(对象锁)

public synchronized void test(){
        //doSomething。。。。。
}  

2 静态方法加锁(类锁)

public synchronized static void test(){
        //doSomething。。。。。
}

3 对象加锁(对象锁)

Object object = new Object();
public void test(){
    synchronized (object){
      //doSomeing。。。。
    }
}

4 方法中给类加锁(类锁)

public void test(){
      synchronized (SocketServerTest.class){
          //doSomeing。。。。
      }
}

思考:

对象锁锁住对象, 若其他方法块需要获取当前对象锁则必须排队等待释放;  类锁(也称为类锁)则是在使用类加锁或静态方法加锁时需要排队

那么问题来了若类锁和对象锁共存是一种什么样的情况呢, 我们给静态方法和普通方法都加上锁

对于以下代码我们可以预测可能会有两种情况

1对象锁和类锁为互斥, 需要排队 预测结果 test1 test2 tStatic1 tStatic2

2对象锁和类锁无关联,各自作用域不同 预测结果  tStatic1 tStatic2  test1 test2


public static void main(String[] args) throws InterruptedException {
Test test = new Test();
Thread t1 = new Thread(()->test.test1());
Thread t2 = new Thread(()->test.test2());
Thread tStatic1 = new Thread(()->Test.testStatic1());
Thread tStatic2 = new Thread(()->Test.testStatic2());
t1.start();
   //保证t2在t1之后获取锁
Thread.sleep(300);
t2.start();
//保证tStatic1在t2之后获取锁
Thread.sleep(300);
tStatic1.start();
//保证tStatic2在tStatic1之后获取锁
Thread.sleep(300);
tStatic2.start();
}


public static class Test{

public synchronized void test1() {
//休眠5秒
try {
Thread.sleep(5*1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("test1");
}

public void test2() {
synchronized (this){
System.out.println("test2");
}
}

public synchronized static void testStatic1(){
//休眠3秒
try {
Thread.sleep(3*1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("testStatic1");
}

public static void testStatic2(){
synchronized (Test.class){
System.out.println("testStatic2");
}
}
}


打印结果:

testStatic1
testStatic2
test1
test2

从以上结果可以看出,对象锁和类锁完全互不影响

注:需要补充的是synchronized为重入锁, 下面一段小示例

public static void main(String[] args) throws InterruptedException {
    Test test = new Test();
    test.testA();
}

//inner class
public static class Test{

    //使用synchronized重入锁
    public synchronized void testA(){
        System.out.println("testA");
        testB();
    }
   //方法testB 在方法testA 未释放锁的情况下,运行同步代码(同一个线程)
private synchronized void testB(){ System.out.println("testB"); } }

原文地址:https://www.cnblogs.com/xieyanke/p/12160764.html