synchronized 到底锁的是谁?

这篇具有很好参考价值的文章主要介绍了synchronized 到底锁的是谁?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

synchronized 到底锁的是谁?
修饰方法:
1、静态方法
2、非静态方法,锁住的是方法的调用者
修饰代码块

1、synchronized修饰非静态方法 锁住的是方法的调用者

锁住实例

流程:
1、线程A先拿到synModel对象然后给这个 synModel对象加上锁–接着等3s执行输出结束
2、线程B等1s后运行,此时 synModel对象 已经被 A拿到,所以他只能等待 等3s后,线程A释放 synModel对象,然后获取对象执行输出结束

public class SynchronizedTest {

    public static void main(String[] args) throws InterruptedException {
        SynModel synModel = new SynModel();
        new Thread(()->{
            synModel.fun1();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            synModel.fun2();
        },"B").start();
    }
}
class SynModel{

    public synchronized void fun1()  {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1...");
    }
    public synchronized void fun2(){
        System.out.println("2...");
    }
}

情况1 不会排队

注意:下面这种情况是不会排队的,因为锁的是实例。

public class SynchronizedTest {

    public static void main(String[] args) throws InterruptedException {
        SynModel synModel1 = new SynModel();
        SynModel synModel2 = new SynModel();
        new Thread(()->{
            synModel1.fun1();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            synModel2.fun2();
        },"B").start();
    }
}
class SynModel{

    public  synchronized void fun1()  {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1...");
    }
    public  synchronized void fun2(){
        System.out.println("2...");
    }
}

2 、修饰静态方法

只是把SynModel中的方法变成了静态的,注意此时锁住的是 SynModel这个类,不是锁的实例。会排队 先输出1后输出2

public class SynchronizedTest {

    public static void main(String[] args) throws InterruptedException {
        SynModel synModel1 = new SynModel();
        SynModel synModel2 = new SynModel();
        new Thread(()->{
            synModel1.fun1();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            synModel2.fun2();
        },"B").start();
    }
}
class SynModel{

    public static synchronized void fun1()  {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1...");
    }
    public static synchronized void fun2(){
        System.out.println("2...");
    }
}

3、代码块

synchronized (this){}锁住的是SynModel这个对象。可以看到循环的五次都是同一个SynModel对象。所以五个线程 某个时刻只能有一个线程拿到这个SynModel对象 这个资源。
每个线程会依次输出start end


public class SynchronizedTest {
    public static void main(String[] args) {
        final SynModel synModel = new SynModel();
        for (int i = 0; i < 5; i++) {
            synModel.fun3();
        }
    }
}
class SynModel{
    public void fun3(){
        synchronized (this){
            System.out.println("start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("end");
        }
    }

}

如果把对象放在循环里面,此时就是五个线程拿五个资源了。并没有去争夺资源

public class SynchronizedTest {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            final SynModel synModel = new SynModel();
            new Thread(()->{
                synModel.fun3();
            }).start();
        }
    }
}
class SynModel{
    public void fun3(){
        synchronized (this){
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
        }
    }

}

锁住SynModel.class 此时五个线程就会竞争,因为锁住的是 SynModel这个类,而不是实例对象了。文章来源地址https://www.toymoban.com/news/detail-745788.html

public class SynchronizedTest {

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            final SynModel synModel = new SynModel();
            new Thread(()->{
                synModel.fun3();
            }).start();
        }
    }
}
class SynModel{

  

    public void fun3(){
        synchronized (SynModel.class){// this SynModel.class
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
        }
    }

}

到了这里,关于synchronized 到底锁的是谁?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 私钥和公钥到底是谁来加密、谁来解密?

    1.  应用场景 场景1(第一种用法):用于信息加解密,此时使用公钥加密,私钥解密。 场景2(第二种用法):用于数字签名,此时使用私钥签名,公钥验签。 有点混乱,不要去硬记,你只要这样想即可: - 既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解

    2023年04月15日
    浏览(73)
  • 多线程Synchronized锁的使用与线程之间的通讯

    多线程同时对同一个全局变量做写操作,可能会受到其他线程的干扰,就会发生线程安全问题。 Java中的全局变量是存放在堆内存中的,而堆内容对于所有线程来说是共享的。 比如下面一个简单的代码案例: 代码比较简单,我们看下面控制台的打印: 可以看到两个线程之间

    2024年02月04日
    浏览(40)
  • 测试工程师的最大疑问:项目上线出现严重Bug,到底是谁的责任?

    各位小伙伴们还记上个月小红书APP崩溃闪退,导致大批用户卸载APP重装的事故吗?闪退Bug从凌晨持续到第二天上午。 事发第二天,就有研发在线承认了,因为自己的失误导致了这次事件,评论区也有人担心博主会不会失去工作。 这件事会到此为止吗?有研发人员承认了错误

    2024年02月11日
    浏览(45)
  • 深度思考,AI项目的人工智能到底引领的是什么?

    欢迎来到我们人工智能的创新AIMQ殿堂,这里不仅仅是一个项目,更是我们对未来技术的深度思考。让我们一同穿越数字时空,感受人工智能引领技术之舞的重要性,融入中国文化元素,探索未知的技术宇宙。初步命名为AIMQ,是因为IMMQY项目; 项目背景:人工智能的魔法时代

    2024年01月18日
    浏览(55)
  • 设计模式学习笔记 - 面向对象 - 1.面向对象到底讨论的是什么

    面向对象编程( OOP )的全称是 Object Oriented Programming 。 面向对象编程语言( OOPL )的全称是 Object Oriented Programming Language 。 面向对象编程中有两个非常重要的概念,就是类( Class )和对象( Object )。面向对象编程这个概念第一次使用是在 SmallTalk 这种编程语言中,它也被认

    2024年02月22日
    浏览(45)
  • 【周末闲谈】人工智能热潮下的AIGC到底指的是什么?

    生成式人工智能AIGC(Artificial Intelligence Generated Content)是人工智能1.0时代进入2.0时代的重要标志。 个人主页:【😊个人主页】 系列专栏:【❤️周末闲谈】 ✨第一周 二进制VS三进制 ✨第二周 文心一言,模仿还是超越? ✨第二周 畅想AR 当我查阅资料时发现明明是火遍全网

    2024年02月13日
    浏览(47)
  • Java里面加锁的方式

    使用synchronized可以实现对代码块或方法的加锁。当一个线程获取到锁后,其他线程将被阻塞,直到该线程释放锁。 示例代码如下: ReentrantLock是Java提供的显式锁(Explict Lock)实现类。它使用lock()和unlock()方法来加锁和释放锁,可以实现更灵活的加锁操作。 示例代码如下

    2024年02月10日
    浏览(59)
  • Java中锁的解决方案

    在上一篇文章中,介绍了什么是锁,以及锁的使用场景,本文继续给大家继续做深入的介绍,介绍JAVA为我们提供的不同种类的锁。 JAVA为我们提供了种类丰富的锁,每种锁都有不同的特性,锁的使用场景也各不相同。由于篇幅有限,在这里只给大家介绍比较常用的几种锁。我

    2024年02月02日
    浏览(32)
  • java线程-synchronized详解

    解决线程原子性问题,最常见的手段就是加锁,Java提供了两种加锁的方式,一个synchronized隐式锁,另外一个是通过J.U.C框架提供的Lock显式加锁。本文主要介绍一个Synchronized的实现方式。 synchronized解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是

    2024年02月10日
    浏览(44)
  • Java——》synchronized的原理

    推荐链接:     总结——》【Java】     总结——》【Mysql】     总结——》【Redis】     总结——》【Kafka】     总结——》【Spring】     总结——》【SpringBoot】     总结——》【MyBatis、MyBatis-Plus】     总结——》【Linux】     总结——》【MongoDB】    

    2024年02月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包