Synchronized锁对象详解

synchronized 是我们的同步的一种选择,加锁就要有对应的钥匙
这个钥匙分为 当前类对象当前class对象 , 第三方对象

synchronized 可以修饰 变量方法
我们以方法举例可以有如下的几种情况:

  • 修饰静态方法 , 这里默认的锁就是当前类的class对象
public synchronized static void t0(){
	// code
}
  • 修饰非静态方法 , 这里默认的锁就是当前类的实例对象
public synchronized void t1(){
	// code
}
  • 同步代码块中锁

    • 锁一个对象
    public void t2() {
          synchronized (o) {
    		// code
    	}
    }
    
    • 锁一个对象的class
    public void t3() {
          synchronized (o.getClass()) {
    		// code
    	}
    }
    

经过验证,总结如下:

我们只有两种锁,对象锁和Class锁,Class锁允许所有的Class相同的对象都拿到资源,对象锁就单纯的只有这个对象才能获取到锁。其中,静态都是 锁类的 class。其他的时候我们都是习惯于单纯的锁对象。



具体的验证代码如下:

public class MySynchronized {
    public int id;
    public String name;
    
    public Object o = new Object();

    public synchronized static void t0(){
        System.out.println(Thread.currentThread().getName()+"  invoked  "+" static t0 method start");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"  invoked  "+" static t0 method end");
        System.out.println();

    }

    public synchronized void t1()  {
        System.out.println(Thread.currentThread().getName()+"  invoked  "+"t1 start");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"  invoked  "+"t1 end");
        System.out.println();
    }

    public void t2() {
        synchronized (o) {
            System.out.println(Thread.currentThread().getName()+"  invoked  "+"t2 start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"  invoked  "+"t2 end");
            System.out.println();
        }
    }

    public void t3() {
        synchronized (o.getClass()) {
            System.out.println(Thread.currentThread().getName()+"  invoked  "+"t3 start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"  invoked  "+"t3 end");
            System.out.println();
        }
    }

    public static void main(String[] args) {
        // TODO 同步方法测试
        // 同一个实例对象,哪个线程先调哪个就先得
        MySynchronized test1 = new MySynchronized();
        Thread t1 = new Thread(test1::t1);
        Thread t2 = new Thread(test1::t1);
        // thread1.start();
        // thread2.start();

        // TODO 静态方法测试
        // 锁的是class,同一个class 先到先得
        Thread t3 = new Thread(MySynchronized::t0);
        Thread t4 = new Thread(MySynchronized::t0);
        Thread t5 = new Thread(MySynchronized::t0);
        // t3.start();
        // t4.start();
        // t5.start();

        // TODO 测试不同实例的 成员变量
        System.out.println(new MySynchronized().o.equals(new MySynchronized().o));
        MySynchronized temp1 = new MySynchronized();
        MySynchronized temp2 = new MySynchronized();
        Thread t6 = new Thread(temp1::t2);
        Thread t7 = new Thread(temp2::t2);
        // t6.start();
        // t7.start();
        // TODO 测试同实例 成员变量
        Thread t8 = new Thread(temp2::t2);
        // t7.start();
        // t8.start();

        // TODO 测试不同实例 成员变量.class
        Thread t9 = new Thread(temp2::t3);
        Thread t0 = new Thread(temp2::t3);
        t0.start();
        t9.start();

    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值