小言_互联网的博客

八个例子彻底理解锁

312人阅读  评论(0)

例子一:一个对象,两个加锁方法
下面代码运行结果是先输出打电话还是发短信

public class Test1 {
    public static void main(String[] args) {
        Phone phone= new Phone();
         //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}
class Phone{
  public  synchronized  void sendMessage(){
      System.out.println("发短信");
  }

  public  synchronized  void call(){
      System.out.println("打电话");
  }
}

例子二:在例子一的基础上让第一个加锁方法睡眠4秒再执行
下面代码运行结果是先输出打电话还是发短信


public class Test1 {
    public static void main(String[] args) {
        Phone phone= new Phone();
         //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone.sendMessage();
        },"A").start();
        //捕获
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}
class Phone{
   //synchronized 锁的对象是方法的调用者
   //两个方法调用的是同个锁即Phone,说先获取到就谁先输出
  public  synchronized  void sendMessage(){
      try {
      //睡眠4秒再执行
          TimeUnit.SECONDS.sleep(4);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println("发短信");
  }
 //synchronized 锁的对象是方法的调用者
  public  synchronized  void call(){
      System.out.println("打电话");
  }
}

例子三:一个普通方法hello和一个加锁的方法
下面代码运行结果是先输出你好还是发短信


public class Test2 {
    public static void main(String[] args) {
        Phone2 phone= new Phone2();
        //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.hello();
        },"B").start();
    }
}
class Phone2{
    
    public  synchronized  void sendMessage(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //这里没有锁,不是同步方法,不受锁的影响
    public  void hello(){
        System.out.println("你好");
    }
}

例子四:两个对象,两个加锁方法
下面代码运行结果是先输出打电话还是发短信

//两个对象,两个同步方法,先打电话后发短信
public class Test2 {
    public static void main(String[] args) {
        //两个对象
        Phone2 phone1= new Phone2();
        Phone2 phone2= new Phone2();
        //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone1.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}
class Phone2{

    public  synchronized  void sendMessage(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public  synchronized  void call(){
        System.out.println("打电话");
    }

 
}

例子五:一个对象,两个static加锁方法
下面代码运行结果是先输出打电话还是发短信


public class Test3 {
    public static void main(String[] args) {
        Phone3 phone= new Phone3();
        //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}
class Phone3{
   //static静态方法
    //类一加载就有了 锁的class类
    //所以此时锁的是同一个锁
    public static synchronized  void sendMessage(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public static synchronized  void call(){
        System.out.println("打电话");
    }


}

例子六:两个对象,两个static加锁方法
下面代码运行结果是先输出打电话还是发短信


public class Test3 {
    public static void main(String[] args) {
        //两个对象的class类模板只有一个,static锁的是class
        Phone3 phone1= new Phone3();
        Phone3 phone2= new Phone3();
        //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone1.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}
class Phone3{
   //static静态方法
    //类一加载就有了 锁的class类
    //所以此时锁的是同一个锁
    public static synchronized  void sendMessage(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public static synchronized  void call(){
        System.out.println("打电话");
    }
}

例子七:一个对象,一个static加锁方法,一个普通加锁同步方法
下面代码运行结果是先输出打电话还是发短信


public class Test4 {
    public static void main(String[] args) {
        Phone4 phone= new Phone4();
        //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone.call();
        },"B").start();
    }
}
class Phone4{
    //静态同步方法,锁的类模板
    public static synchronized  void sendMessage(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //普通同步方法,锁的调用方法
    public  synchronized  void call(){
        System.out.println("打电话");
    }


}

例子八:两个对象,一个static加锁方法,一个普通加锁同步方法
下面代码运行结果是先输出打电话还是发短信


public class Test4 {
    public static void main(String[] args) {

        Phone4 phone1= new Phone4();
        Phone4 phone2= new Phone4();
        //这里的->是lambda表达式的写法
        new Thread(()-> {
            phone1.sendMessage();
        },"A").start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(()->{
            phone2.call();
        },"B").start();
    }
}
class Phone4{
    //静态同步方法,锁的类模板
    public static synchronized  void sendMessage(){
        try {
            TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    //普通同步方法,锁的调用方法
    public  synchronized  void call(){
        System.out.println("打电话");
    }


}

例子一运行结果:发短信 打电话
例子二运行结果:等待4秒后输出 发短信 打电话
例子三运行结果:先输出你好 后输出 发短信
例子四运行结果:先输出打电话 再发短信
例子五运行结果:先发短信后打电话
例子六运行结果:先发短信后打电话
例子七运行结果:先打电话,后发短信
例子八运行结果:先打电话,后发短信

小结

static synchronized 锁的是class
synchronized 锁的是对象
谁先获取到对象谁就先执行

声明:本文为学习狂神说java的juc并发编程所做的笔记,狂神说javajuc并发编程地址:https://www.bilibili.com/video/BV1B7411L7tE?p=11


转载:https://blog.csdn.net/weixin_42369886/article/details/106000740
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场