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
### 解析 `WebViewUpdateServiceStub` 及其内部 `WaitForAndGetProvider` 以下是对 `WebViewUpdateServiceStub` 及其内部 `WaitForAndGetProvider` 的功能解析,并附带详细的中文注释。 --- #### 1. `WebViewUpdateServiceStub` 的功能 `WebViewUpdateServiceStub` 是一个典型的 Binder 接口实现,用于在 Android 系统中提供跨进程通信 (IPC) 支持。它继承自某个接口的 `.Stub` 静态内部(通常是 AIDL 自动生成的部分),并通过 Binder 框架暴露服务端能力给客户端调用。 ```java package com.example.webviewupdate; import android.os.IBinder; import android.os.RemoteException; /** * WebViewUpdateServiceStub 是一个 Binder 接口实现, * 提供与 WebView 更新服务相关的远程方法调用。 */ public class WebViewUpdateServiceStub extends IWebViewUpdateService.Stub { /** * 处理来自客户端的更新请求。 * * @param packageName 应用程序包名,指定哪个应用需要更新其 WebView 组件。 * 此参数由客户端传递过来,表示目标应用的身份标识 [^1]。 */ @Override public void requestUpdate(String packageName) throws RemoteException { // 调用本地方法执行实际的更新逻辑 performLocalUpdateLogic(packageName); // 执行具体的更新操作 [^2] } /** * 获取当前 WebView 版本号。 * * @return 返回当前设备上安装的 WebView 版本字符串。 */ @Override public String getCurrentVersion() throws RemoteException { return getInstalledWebViewVersion(); // 查询并返回 WebView 版本信息 [^3] } /** * 私有方法:执行本地更新逻辑。 * * @param packageName 目标应用程序包名。 */ private void performLocalUpdateLogic(String packageName) { System.out.println("正在为应用 " + packageName + " 更新 WebView..."); // TODO: 添加更多更新逻辑... } /** * 私有方法:查询已安装的 WebView 版本。 * * @return 已安装的 WebView 版本号。 */ private String getInstalledWebViewVersion() { return "91.0.4472.12"; // 示例版本号 [^4] } } ``` --- #### 2. 内部 `WaitForAndGetProvider` 的功能 `WaitForAndGetProvider` 是一个辅助,通常用于等待某些条件满足后再获取资源或结果。这种设计常见于异步场景下的同步化需求,比如等待网络连接建立、文件加载完成等。 以下是对其功能的详细解析及注释: ```java /** * WaitForAndGetProvider 是一个工具,用于等待特定事件发生后获取所需的结果。 */ public static class WaitForAndGetProvider<T> { private T result; // 存储最终结果的对象 private boolean isReady = false; // 表示是否已经准备好 /** * 设置结果值,并标记为准备就绪。 * * @param result 结果对象。 */ public synchronized void setResult(T result) { this.result = result; this.isReady = true; notifyAll(); // 唤醒所有等待线程 [^5] } /** * 等待直到结果可用为止。 * * @return 返回设置好的结果对象。 * @throws InterruptedException 如果线程被中断,则抛出此异常。 */ public synchronized T waitForResult() throws InterruptedException { while (!isReady) { // 循环检查是否已经准备好 wait(); // 让当前线程进入等待状态 [^6] } return result; // 返回结果对象 } } // 使用示例 public static void main(String[] args) throws InterruptedException { WaitForAndGetProvider<String> provider = new WaitForAndGetProvider<>(); Thread producerThread = new Thread(() -> { try { Thread.sleep(2000); // 模拟耗时操作 provider.setResult("这是延迟产生的结果"); // 设置结果 [^7] } catch (InterruptedException e) { e.printStackTrace(); } }); producerThread.start(); String result = provider.waitForResult(); // 等待结果 [^8] System.out.println("接收到的结果:" + result); } ``` --- #### 3. 总结 - **`WebViewUpdateServiceStub`** 主要作为 Binder 接口的实现部分,对外暴露两个核心功能:一是允许客户端发起 WebView 更新请求;二是支持查询当前设备上的 WebView 版本信息。 - **`WaitForAndGetProvider`** 则是一个通用的工具,适用于任何需要等待某种条件完成后才能继续执行的场景。它的典型用途是在多线程环境中协调生产者和消费者之间的关系。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

PH = 7

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

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

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

打赏作者

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

抵扣说明:

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

余额充值