synchronized(this)、synchronized(.class)、锁静态方法、方法区别?

简介: synchronized(this)、synchronized(.class)、锁静态方法、方法区别?

一、synchronized 与 synchronized static区别?


synchronized:对像的当前实例进行加锁,防止其他线程同时访问该类实例的所有synchronized块。

synchronized static:是限制线程同时访问jvm中该类的所有实例同时访问对应的代码块,且该类的所有代码块共用一把锁。

pulbic class syncMethod(){
       public synchronized void syncA(){}
       public synchronized void syncB(){}
       public static synchronized void staticA(){}
       public static synchronized void staticB(){}
}

假设上面的类有四个方法,然后有两个实例a,b调用,那么哪些可以同时被访问呢?

1、a.syncA()  和 a.syncB()。

2、a.syncA()  和 b.syncB()。

3、a.staticA() 和 b.staticB()。

4、a.staticA() 和 syncMethod.staticB()。

这里我们可以根据上面两个定律判断:

1、这个肯定是可以加锁成功,两个线程不能同时访问。

2、这个肯定加锁失败,两个线程可以同时访问。

3、这个因为是静态,而且是不同的实例,根据定律也是可以加锁成功,两个线程不能同时访问。

4、这里因为一个是实例方法锁,一个是类方法锁,锁的对象不同,所以可以被同时访问。


二、synchornized(this)和synchronized(.class)


对象锁只对当前对象进行加锁,锁this和synchronized普通方法一样,只对调用的实例进行加锁,而锁.class是指对类加锁。


synchornized(this)

public class Sync823 {
    public static void main(String[] args) {
        Service823 service823 = new Service823();
        ThreadA823 threadA823 = new ThreadA823(service823);
        threadA823.setName("鸣人");
        threadA823.start();
        Service823 service82311 = new Service823();
        ThreadB823 threadB823 = new ThreadB823(service823);
        threadB823.setName("佐助");
        threadB823.start();
    }
}
class Service823{
    void thread823(){
        synchronized (this){
            for (int i = 0; i < 100; i++) {
                if(Thread.currentThread().getName().equals("鸣人")){
                    System.out.println("鸣人释放 螺旋丸");
                    continue;
                }
                System.out.println("佐助释放 千鸟");
            }
        }
    }
}
class ThreadA823 extends Thread{
    private Service823 service823;
    ThreadA823(Service823 service823){
        this.service823 = service823;
    }
    @Override
    public void run() {
        service823.thread823();
    }
}
class ThreadB823 extends Thread{
    private Service823 service823;
    ThreadB823(Service823 service823){
        this.service823 = service823;
    }
    @Override
    public void run() {
        service823.thread823();
    }
}
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟

从上面代码可以看到,当锁this的时候,当是同一个实例,这时候是上锁成功,两个线程不会同时访问,和前面的synchronized修饰普通方法一样,但如果换成 不同的实例,则不会互斥。

public static void main(String[] args) {
        Service823 service823 = new Service823();
        ThreadA823 threadA823 = new ThreadA823(service823);
        threadA823.setName("鸣人");
        threadA823.start();
        Service823 service82311 = new Service823();
        ThreadB823 threadB823 = new ThreadB823(service82311);
        threadB823.setName("佐助");
        threadB823.start();
    }
佐助释放 千鸟
佐助释放 千鸟
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
佐助释放 千鸟
佐助释放 千鸟

synchronized(.class)

 synchronized (Service823.class){
            for (int i = 0; i < 100; i++) {
                if(Thread.currentThread().getName().equals("鸣人")){
                    System.out.println("鸣人释放 螺旋丸");
                    continue;
                }
                System.out.println("佐助释放 千鸟");
            }
        }
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
鸣人释放 螺旋丸
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟
佐助释放 千鸟


这时候会发现,无论是创建几个实例,都会互斥成功,所以锁.class锁的是这个类,并不是实例。


相关文章
|
存储 SQL 缓存
mysql覆盖索引详解——like模糊全匹配中使用索引
mysql覆盖索引详解——like模糊全匹配中使用索引
1551 0
mysql覆盖索引详解——like模糊全匹配中使用索引
|
存储 缓存 NoSQL
防止订单重复提交或支付分布式锁方案设计
防止订单重复提交或支付分布式锁方案设计
1606 0
JUC并发—15.红黑树详解
本文主要介绍了目录红黑树的定义性质和推论、红黑树的旋转操作、红黑树之添加结点的方法和红黑树之删除结点的方法。
JUC并发—15.红黑树详解
springCloud之服务降级熔断Hystrix、OpenFeign
springCloud之服务降级熔断Hystrix、OpenFeign
1492 0
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
中间件 Java 调度
Seata两阶段提交AT模式详解
Seata两阶段提交AT模式详解
1091 0
Seata两阶段提交AT模式详解
|
存储 Java 开发者
HashMap线程安全问题大揭秘:ConcurrentHashMap、自定义同步,一文让你彻底解锁!
【8月更文挑战第24天】HashMap是Java集合框架中不可或缺的一部分,以其高效的键值对存储和快速访问能力广受开发者欢迎。本文深入探讨了HashMap在JDK 1.8后的底层结构——数组+链表+红黑树混合模式,这种设计既利用了数组的快速定位优势,又通过链表和红黑树有效解决了哈希冲突问题。数组作为基石,每个元素包含一个Node节点,通过next指针形成链表;当链表长度过长时,采用红黑树进行优化,显著提升性能。此外,还介绍了HashMap的扩容机制,确保即使在数据量增大时也能保持高效运作。通过示例代码展示如何使用HashMap进行基本操作,帮助理解其实现原理及应用场景。
315 1
|
JavaScript 前端开发
【Vue 3】如何实现动态表单生成器的拖拽功能?
【Vue 3】如何实现动态表单生成器的拖拽功能?
|
Docker 容器
docker 常用指令(启动,关闭,查看运行状态)
docker 常用指令(启动,关闭,查看运行状态)
625 1
|
关系型数据库 MySQL Linux
在Linux中,如何备份一个数据库?
在Linux中,如何备份一个数据库?

热门文章

最新文章