静态内部类与锁

首先,有一个例子

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.

时间: 2024-09-29 09:21:21

静态内部类与锁的相关文章

无锁模式的Vector

这两天学习无锁的并发模式,发现相比于传统的 同步加锁相比,有两点好处1.无锁 模式 相比于 传统的 同步加锁  提高了性能 2.无锁模式 是天然的死锁免疫 下来介绍无锁的Vector--- LockFreeVector 它的结构是: private final AtomicReferenceArray<AtomicReferenceArray<E>> buckets; 从这里我们可以看到,它的内部是采用的是 无锁的引用数组, 数组嵌套数组 相当于一个二维数组,它的大小可以动态的进行

有关Java 锁原理

锁 锁是用来锁东西的,让别人打不开也看不到!在线程中,用这个“锁”隐喻来说明一个线程在“操作”一个目标(如一个变量)的时候,如果变量是被锁住的,那么其他线程就对这个目标既“操作”不了(挂起)也无法看到目标的内容!对Java并发包,锁的实现基本在java.util.concurrent.locks包中,说“基本”是因为,在java.util.concurrent中还有CountDownLatch(可以看成带计数器的锁),CyclicBarrier,Semaphore(类似于信号量,但是也可以看成一

使用静态内部类实现单例设计模式

前几天看了下公司代码中的一个单例类,发现居然是用静态内部类实现的.后面在网上找了下资料,发现使用静态内部实现的单例是懒加载的且线程安全. 从网上资料得出如下结论:加载一个类时,其内部类不会同时被加载.一个类被加载,当且仅当其某个静态成员(静态域.构造器.静态方法等)被调用时发生. 一.代码 package com.zxy.test; /** * 使用静态内部类实现的单例类 * @author ZENG.XIAO.YAN * @date 2017-08-08 10:29:20 * @version

可重入锁 公平锁 读写锁

1.可重入锁 如果锁具备可重入性,则称作为可重入锁. ========================================== (转)可重入和不可重入 2011-10-04 21:38 这种情况出现在多任务系统当中,在任务执行期间捕捉到信号并对其进行处理时,进程正在执行的指令序列就被信号处理程序临时中断.如果从信号处理程序返回,则继续执行进程断点处的正常指令序列,从重新恢复到断点重新执行的过程中,函数所依赖的环境没有发生改变,就说这个函数是可重入的,反之就是不可重入的.众所周知,在进

java并发 lock锁

Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了,那么为什么还需要提供Lock?这个问题将在下面进行阐述.本文先从synchronized的缺陷讲起,然后再讲述java.util.concurrent.locks包

Java并发编程深入学习——Lock锁

Lock锁介绍 ??在Java 5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.Java 5.0 增加了一种新的机制:ReentrantLock.它并不是一种替代内置加锁的方法,而是当内置加锁机制不适用时,作为一种可选择的高级功能. Lock接口 Lock接口位于java.util.concurrent.locks包中,它定义了一组抽象的加锁操作. public interface Lock { //获取锁 void lock(); // 如果当

06 锁:可重入锁 公平锁 读写锁

1.可重入锁 如果锁具备可重入性,则称作为可重入锁. 像synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制: 基于线程的分配,而不是基于方法调用的分配. 举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2, 此时线程不必重新去申请锁,而是可以直接执行方法method2. class MyClass { public synch

java并发编程的艺术——第五章总结(Lock锁与队列同步器)

Lock锁 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同时访问共享资源(但有些锁可以允许多个线程访问共享资源,如读写锁). 在Lock接口出现前,java使用synchronized关键字实现锁的功能,但是在javaSE5之后,并发包中提供了Lock接口(以及其实现类)用来实现锁的功能. Lock提供了与synchronized相似的功能,但必须显示的获取锁与释放锁,虽然不及隐式操作方便,但是拥有了锁获取与释放的可操作性.可中断的锁获取与超时获取锁等多重功能. 提供

《Java并发编程的艺术》--Java中的锁

No1: Lock接口 Lock lock = new ReentrantLock(); lock.lock(); try{ }finally{ lock.unlock(); } No2: 不要讲获取锁的过程写在try块中,因为如果在获取锁(自定义锁的实现)时发生了异常,异常抛出的同时,也会导致锁无故释放 No3: No4: 队列同步器(同步器)是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作,并发包的作者期望它能