【第四章】JUC之多线程锁Synchronized#8种应用场景浅析

笔记大纲
  • 标准访问,先打印短信还是邮件(先短信后邮件)
  • 停4秒在短信方法内,先打印短信还是邮件(先短信后邮件)
  • 普通hello方法,先打印短信还是hello(先Hello后短信)
  • 现在有两部手机,先打印短信还是邮件(先邮件后短信)
  • 两个静态同步方法,1部手机,先打印短信还是邮件(先短信后邮件)
  • 两个静态同步方法,2部手机,先打印短信还是邮件(先短信后邮件)
  • 1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件(先邮件后短信)
  • 1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件(先邮件后短信)
  • 总结Synchronized锁范围

例举Synchronized锁8种应用场景,主要目的是为了更好理解Synchronized锁范围。

一、标准访问,先打印短信还是邮件(先短信后邮件)
//先短信后邮件
import java.util.concurrent.TimeUnit;
class Phone {
    public synchronized void sendSMS() throws InterruptedException {
        System.out.println("==========sendSMS短信======");

    }

    public synchronized void sendEmail() throws InterruptedException {
        System.out.println("==========sendEmail邮件======");

    }
}
public class Lock_Problem8 {
    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(() -> {
            try {
                phone.sendSMS();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, "AA").start();
        
		 Thread.sleep(200);//睡眠0.2S,区别线程谁先谁后
        
        new Thread(() -> {
            try {
                phone.sendEmail();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "BB").start();
    }
}
二、停4秒在短信方法内,先打印短信还是邮件(先短信后邮件)
//先短信后邮件
class Phone {
    public synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);  //睡眠4s
        System.out.println("==========sendSMS======");

    }
    public synchronized void sendEmail() throws InterruptedException {
        System.out.println("==========sendEmail======");

    }
}
三、普通hello方法,先打印短信还是hello(先Hello后短信)
//先Hello后短信
import java.util.concurrent.TimeUnit;
class Phone {
    public synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);  //睡眠4s
        System.out.println("==========sendSMS======");
    }
    //没有锁(非同一把锁),不受影响
    public void getHello() {
        System.out.println("==========hello,lindaxia======");
    }
    public static class Lock_Problem8 {
        public static void main(String[] args) throws InterruptedException {
            Phone phone = new Phone();
            Phone phone2 = new Phone();
            new Thread(() -> {
                try {

                    phone.sendSMS();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "AA").start();
            Thread.sleep(200);//睡眠0.2S

            new Thread(() -> {
                try {
                    phone.getHello();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "BB").start();
        }
    }
}
四、 现在有两部手机,先打印短信还是邮件(先邮件后短信)
//先邮件(等4s)后短信--不是同一把锁
import java.util.concurrent.TimeUnit;
class Phone {
    public synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);  //睡眠4s
        System.out.println("==========sendSMS======");

    }
    public synchronized void sendEmail() throws InterruptedException {
        System.out.println("==========sendEmail======");
    }
    public static class Lock_Problem8 {
        public static void main(String[] args) throws InterruptedException {
            Phone phone = new Phone();
            Phone phone2 = new Phone();
            new Thread(() -> {
                try {
                    phone.sendSMS();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "AA").start();
            Thread.sleep(200);//睡眠0.2S

            new Thread(() -> {
                try {
                      phone2.sendEmail();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "BB").start();
        }
    }
}
五、两个静态同步方法,1部手机,先打印短信还是邮件(,先短信后邮件)
//等4S,先短信后邮件
//静态方法是类方法,锁的是Phone的Class,同一把锁
import java.util.concurrent.TimeUnit;
class Phone {
    public static  synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);  //睡眠4s
        System.out.println("==========sendSMS======");

    }
    public static synchronized void sendEmail() throws InterruptedException {
        //TimeUnit.SECONDS.sleep(4);
        System.out.println("==========sendEmail======");
    }
    public static class Lock_Problem8 {
        public static void main(String[] args) throws InterruptedException {
            Phone phone = new Phone();
            Phone phone2 = new Phone();
            new Thread(() -> {
                try {

                    phone.sendSMS();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "AA").start();
            Thread.sleep(200);//睡眠0.2S

            new Thread(() -> {
                try {

                    phone.sendEmail();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "BB").start();
        }
    }
}
六、两个静态同步方法,2部手机,先打印短信还是邮件(先短信后邮件)
//等4S,先短信后邮件--同一把锁
//静态方法是类方法,锁的是Phone的Class,同一把锁
class Phone {
    .....
        
        
    public static class Lock_Problem8 {
        public static void main(String[] args) throws InterruptedException {
            Phone phone = new Phone();
            Phone phone2 = new Phone();
            new Thread(() -> {
                try {
                    phone.sendSMS();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "AA").start();
            Thread.sleep(200);//睡眠0.2S

            new Thread(() -> {
                try {
                    phone2.sendEmail();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "BB").start();
        }
    }
}
七、1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件(先邮件后短信)
//先邮件(等4s)后短信
package com.lindaxia.gmall.jucdemo.jucdemo;

import java.util.concurrent.TimeUnit;

class Phone {
    public static  synchronized void sendSMS() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);  //睡眠4s
        System.out.println("==========sendSMS======");

    }
    public synchronized void sendEmail() throws InterruptedException {
        //TimeUnit.SECONDS.sleep(4);
        System.out.println("==========sendEmail======");

    }
    public static class Lock_Problem8 {
        public static void main(String[] args) throws InterruptedException {
            Phone phone = new Phone();
            new Thread(() -> {
                try {

                    phone.sendSMS();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "AA").start();
            Thread.sleep(200);//睡眠0.2S

            new Thread(() -> {
                try {
                    phone.sendEmail();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "BB").start();
        }
    }
}
八、1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件(先邮件后短信)
//先邮件(等4s)后短信
class Phone {
  .................
    }
    public static class Lock_Problem8 {
        public static void main(String[] args) throws InterruptedException {
            Phone phone = new Phone();
            Phone phone2 = new Phone();
            new Thread(() -> {
                try {

                    phone.sendSMS();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }, "AA").start();
            Thread.sleep(200);//睡眠0.2S

            new Thread(() -> {
                try {
                    phone2.sendEmail();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "BB").start();
        }
    }
}

总结:

   一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法加个普通方法后发现和同步锁无关,换成两个对象后,不是同一把锁了,情况立刻变化。

   synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现为以下3种形式(锁范围):
      对于普通同步方法,锁是当前实例对象this;
      对于静态同步方法,锁是当前类的Class对象(即同一把锁);
      对于同步方法块,锁是Synchonized括号里配置的对象 。


 ☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值