synchronized(this/object/类.class)的区别

synchronized基本介绍:

  1. 在非静态方法前使用,相当于使用this锁;
  2. 在静态方法前使用,相当于使用类锁;
  3. 还可以对某变量进行加锁,object锁;
  4. 静态方法中不可以使用this锁,非静态方法中可以使用类锁,静态方法、非静态方法都可以对object进行加锁;
  5. 类锁、this锁、object锁是相互独立的,不会互相阻塞;
    public synchronized void fun5() {
        System.out.println("实例" + id + "--fun2!!!");
    }
    //等价于
     public  void fun5() {
        synchronized(this){
            System.out.println("实例" + id + "--fun2!!!");
        }
    }
    public static void fun5() {
            System.out.println("实例"+id+"--fun2!!!");
    }

//等价于

    public void fun5() {
        synchronized (Test9.class) {
            System.out.println("实例" + id + "--fun2!!!");
        }
    }

    public  void fun5(Object num) {
        synchronized(Test9.class){
            System.out.println("实例" + id + "--fun2!!!");
        }
        synchronized (num){
            System.out.println("这是一个Object锁!!!");
        }
    }

    //下面这种方法,this锁是会报错的
    public  static void fun6(Object num) {
        synchronized(this){
            System.out.println("实例" + id + "--fun2!!!");
        }
        synchronized (num){
            System.out.println("这是一个object锁!!!");
        }
    }

synchronized(*.class)类锁的相关介绍:

1、当加了类锁的方法或代码块处于访问状态时,该类的其他加了类锁的方法或代码块将拒绝其他线程的访问,但是其他线程可以访问该类的普通方法或者未被占用的this锁或object锁。只有当该方法或代码块执行完毕,其他线程才能访问该类的类锁(注意是方法执行完毕,而不是线程执行完毕。)

在这里插入图片描述

  1. 相关代码演示
//公共类,线程阻塞时间
class Sleep {
    public static void sleepForSecond(int num) throws InterruptedException {
        TimeUnit.SECONDS.sleep(num * 5);
    }
}
//synchronized 关键字探索 --- 静态方法
public class Test9_1 {
    public static void main(String[] args) throws Exception{
        IsStatic isStatic = new IsStatic(1);
        IsStatic isStatic2 = new IsStatic(2);
        int num = 0;
        new Thread(() -> {
            try {
                isStatic.fun1();
                Sleep.sleepForSecond(2);
                System.out.println("线程1阻塞完毕!!!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();
        new Thread(() -> {
            isStatic.fun2();
        }, "B").start();
        new Thread(() -> {
            isStatic.fun3();
        }, "C").start();
        new Thread(() -> {
            try {
                isStatic.fun4();
            }catch (Exception e){}
        }, "D").start();
        new Thread(() -> {
            isStatic2.fun2();
        }, "B").start();
        //写个循环计时
        while (true) {
            System.out.print((++num) + "  秒:");
            Sleep.sleepForSecond(1);
        }
    }
}
class IsStatic {

    private int id;
    public IsStatic(int id){
        this.id = id;
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void fun1() throws InterruptedException {
        synchronized (IsStatic.class) {
            Sleep.sleepForSecond(2);
            System.out.println("实例"+id+"--fun1!!!");
            Sleep.sleepForSecond(5);
        }
    }

    public void fun2() {
        synchronized (IsStatic.class) {
            System.out.println("实例"+id+"--fun2!!!");
        }
    }
    public void fun3() {
        System.out.println("实例"+id+"--fun3!!!");
    }
    public void fun4() throws InterruptedException {
        synchronized (this) {
            Sleep.sleepForSecond(5);
            System.out.println("实例"+id+"--fun4!!!");
        }
    }
}

synchronized(this)对象锁的相关介绍:

1、 当加了this锁(对象锁)处于访问状态时,那么该对象的其他this锁(对象锁)将拒绝其他线程访问,但是它的普通方法或者加了类锁、object锁只要不被其他线程占有,其他线程依然可以进行访问。只有当该方法或代码块执行完毕,其他线程才能访问该对象的对象锁(注意是对象锁,同一个类的不同对象,他们之间的对象锁是没有任何关系的,只有处于同一个对象,他们的对象锁才会发生阻塞。)

在这里插入图片描述

2、 代码演示:

//synchronized关键字探索-非静态方法
public class Test9 {
    public static void main(String[] args) throws Exception {
        noStatic noStatic = new noStatic(1);
        noStatic noStatic2 = new noStatic(2);
        int num = 0;
        new Thread(() -> {
            try {
                noStatic.fun1();
                Sleep.sleepForSecond(2);
                System.out.println("线程1阻塞完毕!!!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "A").start();
        new Thread(() -> {
            noStatic.fun2();
        }, "B").start();
        new Thread(() -> {
            noStatic.fun3();
        }, "C").start();
        new Thread(() -> {
            noStatic2.fun2();
        }, "B").start();
        new Thread(() -> {
            try {
                noStatic.fun4();
            } catch (Exception e) {
            }
        }, "B").start();
        //写个循环计时
        while (true) {
            System.out.print((++num) + "  秒:");
            Sleep.sleepForSecond(1);
        }
    }
}


//this 锁 非静态方法
class noStatic {
    private int id;

    public noStatic(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void fun1() throws InterruptedException {
        synchronized (this) {
            Sleep.sleepForSecond(2);
            System.out.println("实例" + id + "--fun1!!!");
            Sleep.sleepForSecond(5);
        }
    }

    public void fun2() {
        synchronized (this) {
            System.out.println("实例" + id + "--fun2!!!");
        }
    }

    public void fun3() {
        System.out.println("实例" + id + "--fun3!!!");
    }

    public void fun4() throws InterruptedException {
        synchronized (noStatic.class) {
            Sleep.sleepForSecond(2);
            System.out.println("实例" + id + "--fun4!!!");
        }
    }
}

synchronized(object)变量锁的相关介绍:

1、 当object锁(对象锁)处于占用状态时,不管是在同一实例,同一类的不同实例,不同对象的不同实例中,只要和该对象共用同一块内存地址(常量池或堆),并对其增加了同步锁修饰,那么这些变量锁将拒绝其他线程的访问,除非那个处于占用状态的锁执行完毕。

在这里插入图片描述

2、代码演示

public class Test9_2 {
    public static void main(String[] args) throws Exception{
        IsObject isObject = new IsObject();
        Integer num1 = 1;
        Integer num2 = 1;
        Integer num3 = new Integer(1);
        int num = 0;
//开三个线程进行验证
        new Thread(() ->{
            try {
                isObject.fun1(num1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();
        new Thread(() ->{IsObject.fun2(num2);},"B").start();
        new Thread(() ->{IsObject.fun2(num3);},"C").start();
        //写个循环计时
        while (true) {
            System.out.print((++num) + "  秒:");
            Sleep.sleepForSecond(1);
        }
    }
}
class IsObject{
    public  void fun1(Integer num) throws InterruptedException {
        synchronized (num){
            System.out.println("fun1线程"+Thread.currentThread().getName()+"的num:"+num);
            Sleep.sleepForSecond(5);
        }
    }
    public static void fun2(Integer num){
        synchronized (num){
            System.out.println("fun2线程" + Thread.currentThread().getName() + "的num:" + num);
        }
    }
}
.class Lcom/yc/pm/WebViewUpdateServiceStub$WaitForAndGetProvider; .super Lcom/yc/pm/MethodProxy; .source "WebViewUpdateServiceStub.java" # annotations .annotation system Ldalvik/annotation/EnclosingClass; value = Lcom/yc/pm/WebViewUpdateServiceStub; .end annotation .annotation system Ldalvik/annotation/InnerClass; accessFlags = 0xa name = "WaitForAndGetProvider" .end annotation # direct methods .method private constructor <init>()V .registers 1 .line 56 invoke-direct {p0}, Lcom/yc/pm/MethodProxy;-><init>()V return-void .end method .method synthetic constructor <init>(Lcom/yc/pm/WebViewUpdateServiceStub$1;)V .registers 2 .line 56 invoke-direct {p0}, Lcom/yc/pm/WebViewUpdateServiceStub$WaitForAndGetProvider;-><init>()V return-void .end method # virtual methods .method public varargs call(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object; .registers 8 .annotation system Ldalvik/annotation/Throws; value = { Ljava/lang/Throwable; } .end annotation .line 64 invoke-virtual {p2, p1, p3}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; move-result-object v1 .line 65 if-eqz v1, :cond_21 .line 66 invoke-static {v1}, Lcom/yc/pm/Reflect;->on(Ljava/lang/Object;)Lcom/yc/pm/Reflect; move-result-object v0 const-string v2, "packageInfo" invoke-virtual {v0, v2}, Lcom/yc/pm/Reflect;->get(Ljava/lang/String;)Ljava/lang/Object; move-result-object v0 check-cast v0, Landroid/content/pm/PackageInfo; .line 67 if-eqz v0, :cond_21 .line 68 invoke-static {v0}, Lcom/yc/pm/Reflect;->on(Ljava/lang/Object;)Lcom/yc/pm/Reflect; move-result-object v0 const-string v2, "signatures" invoke-static {}, Lcom/yc/pm/SignatureFake;->getSignature()[Landroid/content/pm/Signature; move-result-object v3 invoke-virtual {v0, v2, v3}, Lcom/yc/pm/Reflect;->set(Ljava/lang/String;Ljava/lang/Object;)Lcom/yc/pm/Reflect; .line 71 :cond_21 return-object v1 .end method .method public getMethodName()Ljava/lang/String; .registers 2 .line 59以上代码的作用,并中文注释 const-string v0, "waitForAndGetProvider" return-object v0 .end method以上
05-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PH = 7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值