美文网首页
synchronized线程8锁学习总结

synchronized线程8锁学习总结

作者: 来一斤小鲜肉 | 来源:发表于2023-03-13 23:37 被阅读0次

通过8种情况演示锁运行案例,看看我们到底锁的是什么。
输出结果我会放在最底下。可以思考一下,然后对照,代码都是基于Java8运行。

案例:

情况1:标准访问有a b两个线程,请问先打印邮件还是短信 ?

class Phone{
    public  synchronized void sendEmail(){
        
        System.out.println("-------------sendEmail");

    }
    public  synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone.sendSMS();
        },"b").start();

    }
}

情况2:sendEmail故意停3秒?,请问先打印邮件还是短信 ?

class Phone{
    public  synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public  synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone.sendSMS();
        },"b").start();

    }
}

情况3:添加一个普通的hello方法,请问先打印邮件还是hello

class Phone{
    public  synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public  synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

    public void hello(){
        System.out.println("---------hello");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone.hello();
        },"b").start();

    }
}

情况4:有2部phone , 请问先打印邮件还是短信 ?

class Phone{
    public  synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public  synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

    public void hello(){
        System.out.println("---------hello");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        
        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone2.sendSMS();
        },"b").start();

    }
}

情况5:有2个静态同步方法,有一部phone ,请问先打印邮件还是短信 ?

class Phone{
    public  static synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public  static synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

    public void hello(){
        System.out.println("---------hello");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();


        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone.sendSMS();
        },"b").start();

    }
}

情况6:有2个静态同步方法,有两部phone,请问先打印邮件还是短信 ?


class Phone{
    public  static synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public  static synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

    public void hello(){
        System.out.println("---------hello");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        Phone phone2 = new Phone();


        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone2.sendSMS();
        },"b").start();

    }
}

情况7:有1个静态同步方法,1个普通同步方法,有1部phone_,_请问先打印邮件还是短信 ?

class Phone{
    public  static synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public   synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

    public void hello(){
        System.out.println("---------hello");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();



        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone.sendSMS();
        },"b").start();

    }
}

情况8:有1个静态同步方法,1个普通同步方法,有2部phone_,_请问先打印邮件还是短信 ?

class Phone{
    public  static synchronized void sendEmail(){
        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("-------------sendEmail");

    }
    public   synchronized void sendSMS(){
        System.out.println("-------------sendSMS");
    }

    public void hello(){
        System.out.println("---------hello");
    }

}

public class Lock8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        Phone phone2 = new Phone();


        new Thread(()->{
            phone.sendEmail();
        },"a").start();

        //暂停200ms 保证a先启动
        try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

        new Thread(()->{
            phone2.sendSMS();
        },"b").start();

    }
}

锁的说明:

对于被synchronize关键字修饰普通方法。锁是this。
对于被synchronize关键字修饰static方法。锁是类对象。
对于同步方法块。锁的是synchronize(xxx)括号内的对象。
如果锁对象不同,就不会产生锁的竞争。

8种情况解释说明:

情况1,2:
sendEmail 和sendSMS 都是同步方法。而且锁对象都是phone。所以会产生竞争,从代码执行顺序来看,
sendEmail 先执行,那就先获得锁。sendSMS 则等待sendEmail 执行完毕。
情况3:
hello是个普通方法并未和synchronize修饰的sendEmail方法产生锁的争抢。但sendEmail中睡了3秒,所以hello先输出。
情况4:
有两个phone锁对象,sendEmail 和 sendSMS没有锁的竞争。但sendEmail中睡了3秒,所以sendSMS先输出。
情况5,6:
sendEmail 和 sendSMS 都是静态同步方法,锁对象都是当前类对象。sendEmail 会先抢到锁,sendSMS 进行等待。sendEmail先执行。
情况7:
sendEmail 是静态同步方法,锁对象都是当前类对象。sendSMS 是普通同步方法,锁对象是this。两者没有锁的竞争。但sendEmail中睡了3秒,所以sendSMS先输出。
情况8:
虽然有两个phone对象,但是道理还是和情况7一样。

运行结果:

情况1:

-------------sendEmail
-------------sendSMS

情况2:

-------------sendEmail
-------------sendSMS

情况3:

---------hello
-------------sendEmail

情况4:

-------------sendSMS
-------------sendEmail

情况5:

-------------sendEmail
-------------sendSMS

情况6:

-------------sendEmail
-------------sendSMS

情况7:

-------------sendSMS
-------------sendEmail

情况8:

-------------sendSMS
-------------sendEmail

相关文章

  • iOS开发底层相关基础知识点

    正确使用多线程同步锁@synchronized() YYKit学习笔记

  • Java 中的各种锁

    多线程开发离不开各种锁,下面总结下Java和JDK提供的各种锁机制 synchronized synchroniz...

  • 锁的优化

    在前几天的文章:浅谈Java中的锁:Synchronized、重入锁、读写锁 中我们学习了多线程环境下为了保证线程...

  • 乐观锁和悲观锁

    简单总结:悲观锁是线程访问的时候锁住直接锁住访问数据,java里面的synchronized就是一种悲观锁。乐观锁...

  • 方法锁、对象锁和类锁区别

    方法锁、对象锁和类锁区别 引言:结合synchronized进行分析。 synchronized用来处理多个线程同...

  • ios 线程锁

    ios多线程之线程锁 1.@synchronized的用法 @synchronized(self)的用法: @sy...

  • Java多线程——学习笔记二:Synchronized 锁重入

    Synchronized 锁重入 使用Synchronized的时候,当一个线程获得一个对象的锁,在这个线程里面执...

  • 悲观锁:一个线程得到锁,其它线程挂起,synchronized 乐观锁:一个线程得到锁,其它线程不断重试, cas...

  • 多线程中 synchronized 锁升级,偏向锁>轻量级锁>重

    多线程中 synchronized 锁升级的原理是什么? synchronized 锁升级原理:在锁对象的对象头里...

  • OC知识点整理

    @synchronized线程访问锁@synchronized,代表这个方法加锁, 相当于不管哪一个线程(例如线程...

网友评论

      本文标题:synchronized线程8锁学习总结

      本文链接:https://www.haomeiwen.com/subject/frehrdtx.html