多线程下锁范围-synchronized和static synchronized和普通方法(重要)

176 阅读2分钟

最近看锁机制觉得这是重点,得记录;

**首先记录一下,多线程的实现我们可以通过
**

  1. 继承Thread类

  2. 实现Runnable接口

  3. 实现callable接口(1.5后)

  4. **线程池(可忽略)
    **

首先我先把标题三者锁范围的结论写出来,然后举例分析;

  • synchronized方法:一旦获取锁定,将锁定该对象下的所有synchronized方法,其他线程将无法获取该对象下的任何synchronized方法;但可以获取普通方法!

  • 普通方法:不会有锁定,根据线程的执行先后来执行

  • static synchronized方法:也叫静态 类方法,锁定的是该类,该类产出的任何对象都将在这个类锁中,此处只能锁定静态同步方法,无法锁住同步方法(与synchronized的区别就是synchronized锁的只是当前对象的,当new个t2后就无法锁住,而static synchronized锁的是所有对象下的static synchronized方法),静态同步方法和同步方法用的锁不一样;

    //两个同步方法,当只new一个tt的对象t1时,即两个线程执行t1,
    //会先执行send1后执行send2//如果两个线程调用t1的send1和send3(普通方法)
    //会执行send3后执行send1
    //当new两个tt的对象t1.send1、t2.send2时,
    //t1和t2互不影响,会执行send2后执行send1
    class tt{   
     public synchronized void send1() {    
        try {TimeUnit.SECONDS.sleep(2);System.out.println("我在send1");       
     }
     catch (InterruptedException e) { e.printStackTrace();}} 
    public synchronized void send2(){System.out.println("我在send2");}  
    public void send3(){System.out.println("我在send3");}}
    public static void main(String[] args) throws InterruptedException { 
           tt t1 = new tt();     
       tt t2 = new tt();        
        new Thread(()->{            
            t1.send1();        },"aa").start();       
         Thread.sleep(1);//防止进入cpu的顺序影响      
        new Thread(()->{           
         //t1.send2();           
         t2.send2();            
        //t1.send3();        },"bb").start();    }
    

    //这个执行结果是?(先别看答案哦) class tt{
    public static synchronized void send1() {
    try {TimeUnit.SECONDS.sleep(2);System.out.println("我在send1");
    } catch (InterruptedException e) { e.printStackTrace();}}
    public static synchronized void send2(){System.out.println("我在send2");}
    public void send3(){System.out.println("我在send3");}} public static void main(String[] args) throws InterruptedException {
    tt t1 = new tt();
    tt t2 = new tt();
    new Thread(()->{
    t1.send1(); },"aa").start();
    Thread.sleep(1);
    new Thread(()->{
    t2.send2(); },"bb").start();
    } //结果:先执行send1,再执行send2 //t1在执行send1的sleep时,新对象t2是无法获取到锁对象的send2 //因为整个类的static synchronized方法都被锁住了 //如果将send2的static去除了,重新执行,结果是啥呢? //结果:先执行send2,再执行send1(原因是锁不同了)

说的有点迷糊,有点抽象,尽量理解吧,例子敲两遍就理解了。。。

好啦,今天的不开心就止于此吧,明天依旧光芒万丈发啊,宝贝!

撒花,完结!!!

一个没有梦想的梦想家(想要更好排版,微信同名搜即可)