静态内部类与锁

Posted 起个po名真费劲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了静态内部类与锁相关的知识,希望对你有一定的参考价值。

首先,有一个例子

public class OutClass {
    static class InnerClass1 {
        public void method1(InnerClass2 class2){
            String threadName = Thread.currentThread().getName();
            synchronized (class2) {
                System.out.println(threadName + "进入InnerClass1类中的method1方法");
                for(int i = 0; i < 10; i++){
                    System.out.println("i=" + i);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(threadName + "离开InnerClass1类中的method1方法");
            }
        }
        public synchronized void method2(){
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName +"进入InnerClass1类中的method2方法");
                for(int i = 0; i < 10; i++){
                    System.out.println("i=" + i);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(threadName + "离开InnerClass1类中的method2方法");
        }
    }
    static class InnerClass2{
        public synchronized void method1(){
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + "进入InnerClass2类中的method1方法");
            for(int k = 0; k < 10; k++){
                System.out.println("k=" + k);
                try{
                    Thread.sleep(100);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            System.out.println(threadName + "离开InnerClass2类中的method1方法");
        }
    }
}
public class Run {
    public static void main(String[] args) {
        final InnerClass1 in1 = new InnerClass1();
        final InnerClass2 in2 = new InnerClass2();
        Thread t1 = new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                in1.method1(in2);
            }
        },"T1");
        Thread t2 = new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                in1.method2();
            }
        },"T2");
        Thread t3 = new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                in2.method1();
            }
        }, "T3");
        t1.start();
        t2.start();
        t3.start(); 
    }
}
T1进入InnerClass1类中的method1方法
T2进入InnerClass1类中的method2方法
i=0
i=0
i=1
i=1
i=2
i=2
i=3
i=3
i=4
i=4
i=5
i=5
i=6
i=6
i=7
i=7
i=8
i=8
i=9
i=9
T2离开InnerClass1类中的method2方法
T1离开InnerClass1类中的method1方法
T3进入InnerClass2类中的method1方法
k=0
k=1
k=2
k=3
k=4
k=5
k=6
k=7
k=8
k=9
T3离开InnerClass2类中的method1方法

 

运行这个小例子,会发现是T1和T2是异步,T3与其他两个是同步的,显然T3有锁被T1或者T2拿到了。如上图所示。

首先,T1和T2是异步的很好理解,一个获取的锁是当前对象,一个获取的是类,不是一样的当然是异步。

那么看T3:

将t1.start()这个代码注掉,查看结果:

T2进入InnerClass1类中的method2方法
i=0
T3进入InnerClass2类中的method1方法
k=0
k=1
i=1
k=2
i=2
i=3
k=3
i=4
k=4
k=5
i=5
i=6
k=6
i=7
k=7
k=8
i=8
i=9
k=9
T3离开InnerClass2类中的method1方法
T2离开InnerClass1类中的method2方法

异步的,也就是说T2与T3获取的不是同一个锁。T2获取的是in1。

也就是说T1与T3获取的是同一个锁,T1的锁是in2,T3的锁也是in2.

以上是关于静态内部类与锁的主要内容,如果未能解决你的问题,请参考以下文章

非静态内部类与静态内部类

内部类

片段内部静态类和gradle问题

静态内部类与非静态内部类之间的访问

内部类与静态内部类

kotlin内部类与嵌套类