千家信息网

synchronized加锁this和class的区别是什么

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"synchronized加锁this和class的区别是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔
千家信息网最后更新 2026年11月02日synchronized加锁this和class的区别是什么

本篇内容介绍了"synchronized加锁this和class的区别是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

synchronized 是 Java 语言中处理并发问题的一种常用手段,它也被我们亲切的称之为"Java 内置锁",由此可见其地位之高。然而 synchronized 却有着多种用法,当它修饰不同对象时,其意义也是不同的,下面我们一起来看。

synchronized 用法

synchronized 可以用来修饰普通方法、静态方法和代码块。

① 修饰普通方法

/** * synchronized 修饰普通方法 */public synchronized void method() {    // .......}

当 synchronized 修饰普通方法时,被修饰的方法被称为同步方法,其作用范围是整个方法,作用的对象是调用这个方法的对象。

② 修饰静态方法

/** * synchronized 修饰静态方法 */public static synchronized void staticMethod() {    // .......}

当 synchronized 修饰静态的方法时,其作用的范围是整个方法,作用对象是调用这个类的所有对象。

③ 修饰代码块

为了减少锁的粒度,我们可以选择在一个方法中的某个部分使用 synchronized 来修饰(一段代码块),从而实现对一个方法中的部分代码进行加锁,实现代码如下:

public void classMethod() throws InterruptedException {    // 前置代码...        // 加锁代码    synchronized (SynchronizedExample.class) {        // ......    }        // 后置代码...}

以上代码在执行时,被修饰的代码块称为同步语句块,其作用范围是大括号"{}"括起来的代码块,作用的对象是调用这个代码块的对象。

但以上代码,除了可以加锁 class 之外,还可以加锁 this,具体示例如下:

public void classMethod() throws InterruptedException {    // 前置处理代码...    synchronized (this) {        // ......    }    // 后置处理代码...}

那问题来了,使用 synchronized 加锁 this 和 class 的区别是什么?不都是加锁同一个类吗?

答案还真不是,加锁 this 和 class 区别还是很大的。下面我们通过以下 4 个示例,来看二者之间的区别。

1.加锁 class 共享一个类实例

首先,我们创建 5 个线程,调用同一个对象下 synchronized 加锁的 class 代码,具体示例如下:

import java.util.Date;import java.util.concurrent.TimeUnit;public class SynchronizedExample {    public static void main(String[] args) {        // 创建当前类实例        final SynchronizedExample example = new SynchronizedExample();        // 创建 5 个线程执行任务        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    try {                        // 调用 synchronized 修饰的 class 方法                        example.classMethod();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }).start();        }    }    /**     * synchronized 修饰的 class 方法     * @throws InterruptedException     */    public void classMethod() throws InterruptedException {        synchronized (SynchronizedExample.class) {            System.out.println(String.format("当前执行线程:%s,执行时间:%s",                    Thread.currentThread().getName(), new Date()));            TimeUnit.SECONDS.sleep(1);        }    }}

以上程序的执行结果如下:

从上述结果可以看出,这 5 个线程共享的是同一把锁。

2.加锁 class 创建多个实例

接下来,我们创建 5 个线程,调用不同对象下 synchronized 加锁的 class 代码,具体示例如下:

import java.util.Date;import java.util.concurrent.TimeUnit;public class SynchronizedExample {    public static void main(String[] args) {        // 创建 5 个线程执行任务        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    try {                        // 创建类实例                        SynchronizedExample example = new SynchronizedExample();                        // 调用 synchronized 修饰的 class 方法                        example.classMethod();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }).start();        }    }        /**     * synchronized 修饰的 class 方法     * @throws InterruptedException     */    public void classMethod() throws InterruptedException {        synchronized (SynchronizedExample.class) {            System.out.println(String.format("当前执行线程:%s,执行时间:%s",                    Thread.currentThread().getName(), new Date()));            TimeUnit.SECONDS.sleep(1);        }    }}

以上程序的执行结果如下:

从上述结果可以看出,虽然是不同的对象,但它们使用的仍然是同一把锁。

3.加锁 this 共享一个类实例

接下来,我们创建 5 个线程,调用 synchronized 加锁 this 的示例。首先我们这 5 个线程调用同一个对象的加锁方法,示例代码如下:

import java.util.Date;import java.util.concurrent.TimeUnit;public class SynchronizedExample {    public static void main(String[] args) {        // 创建当前类实例        final SynchronizedExample example = new SynchronizedExample();        // 创建 5 个线程执行任务        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    try {                        // 调用 synchronized 修饰的 this 方法                        example.thisMethod();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }).start();        }    }        /**     * synchronized 修饰的 this 方法     * @throws InterruptedException     */    public void thisMethod() throws InterruptedException {        synchronized (this) {            System.out.println(String.format("当前执行线程:%s,执行时间:%s",                    Thread.currentThread().getName(), new Date()));            TimeUnit.SECONDS.sleep(1);        }    }}

以上程序的执行结果如下:

从上述结果可以看出,以上线程使用的都是同一把锁。

4.加锁 this 创建多个类实例

最后一个示例最为特殊,我们使用 synchronized 加锁 this,让这 5 个线程调用各自创建对象的方法,具体示例如下:

import java.util.Date;import java.util.concurrent.TimeUnit;public class SynchronizedExample {    public static void main(String[] args) {        // 创建 5 个线程执行任务        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    try {                        // 创建(多个)类实例                        SynchronizedExample example = new SynchronizedExample();                        // 调用 synchronized 修饰的 this 方法                        example.thisMethod();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }).start();        }    }        /**     * synchronized 修饰的 this 方法     * @throws InterruptedException     */    public void thisMethod() throws InterruptedException {        synchronized (this) {            System.out.println(String.format("当前执行线程:%s,执行时间:%s",                    Thread.currentThread().getName(), new Date()));            TimeUnit.SECONDS.sleep(1);        }    }}

以上程序的执行结果如下:

从上述结果可以看出,当使用 synchronized 加锁 this 时,如果线程调用的不是同一个对象,那么这些线程之间使用的锁都是自己独立的锁,这个结果就和 synchronized 加锁 class 的结果完全不同了。

"synchronized加锁this和class的区别是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

方法 代码 线程 对象 结果 实例 示例 作用 不同 普通 任务 时间 程序 静态 接下来 多个 范围 处理 之间 内容 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司 广州为想互联网科技有限公司 西安纸贵互联网科技有限公司 互联网巨头科技公司 互联网与科技金融数据 金融科技与互联网金融 科技服务与互联网 互联网科技logo设计 深圳卡尔迅互联网科技有限公司怎么样 富国互联网科技创新基金 智腾互联网科技有限公司 互联网金融科技元年 互联网金融科技公司的优势 富国互联网金融科技混合基金 有人说阿里系是互联网科技企业 35岁以上互联网科技行业 易企秀互联网科技是做什么的 湖北辰鑫科技互联网 第三届互联网大会安防黑科技 长沙易易互联网科技有限公司 上海卓越科技互联网 互联网科技缩写 广州凡科互联网科技 汉立互联网科技有限公司联系电话 互联网科技公司的市场部门 承德科技产业互联网发展 科技互联网的核心竞争力 互联网金融科技元年 互联网科技创业有什么好项目 每日互联网科技新闻
0