首页 > 代码库 > 聊聊synchronized的锁问题
聊聊synchronized的锁问题
本文不会特别深入细致地讨论synchronized,只是做一个通俗易懂的说明,以及看清一类问题的本质,希望能给大家一点启发。
问题描述
有一个类A,提供了三个方法。分别是静态同步方法,非静态同步方法,含有静态代码块的方法
1 class A{ 2 public static synchronized void print1(){ 3 print(); 4 } 5 public synchronized void print2(){ 6 print(); 7 } 8 public void print3(){ 9 synchronized (new Object()){10 print();11 }12 }13 private static void print(){14 while(true){15 String threadName = Thread.currentThread().getName();16 System.out.println(threadName);17 }18 }19 }
请回答一下四种情况的输出结果
1 class Test { 2 // 1.两个线程,同一个类,调用静态同步方法print1 3 @Test 4 public void test1() { 5 Thread thread1 = new Thread(() -> A.print1()); 6 Thread thread2 = new Thread(() -> A.print1()); 7 thread1.start(); 8 thread2.start(); 9 }10 // 2.两个线程,同一个对象,调用非静态同步方法print211 @Test12 public void test2() {13 A a = new A();14 Thread thread1 = new Thread(() -> a.print2());15 Thread thread2 = new Thread(() -> a.print2());16 thread1.start();17 thread2.start();18 }19 // 3.两个线程,不同对象,调用非静态同步方法print220 @Test21 public void test3() {22 Thread thread1 = new Thread(() -> new A().print2());23 Thread thread2 = new Thread(() -> new A().print2());24 thread1.start();25 thread2.start();26 }27 // 4.两个线程,同一个对象,调用普通非静态方法(带有同步代码块)print328 @Test29 public void test4() {30 A a = new A();31 Thread thread1 = new Thread(() -> a.print3());32 Thread thread2 = new Thread(() -> a.print3());33 thread1.start();34 thread2.start();35 }36 }
问题答案
先直接报上答案:
- 一直输出“Thread-1”
- 一直输出“Thread-1”
- 交替输出“Thread-1”和“Thread-2”
- 交替输出“Thread-1”和“Thread-2”
问题本质分析
不废话,直接点出,这四个问题只要明白两件事即可:
- 一个线程是否能执行被同步了的方法,主要看是否能拿到锁对象
- 静态方法的同步锁是类对象本身,非静态方法的同步锁是实例对象本身,同步代码块的同步锁是括号中传入的对象
所以
- 如果两个线程执行方法用到了同一个锁对象,则一个线程执行时,另一个线程必须等待其释放锁才能拿到锁,所以此时两个线程会互斥
所以
- 1中两个线程执行方法的锁对象都是类对象A,所以线程之间互斥
- 2中两个线程执行方法的锁对象都是实例对象a,所以线程之间互斥
- 3中两个线程执行方法的锁对象分别是new出来的两个实例对象a,所以线程互不影响
- 4中两个线程执行方法的锁对象分别是new出来的两个实例对象object,所以线程互不影响
Game Over
聊聊synchronized的锁问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。