Chapter2 八锁问题
看了一段时间狂神感觉讲的不够清晰,然后又发现了周阳老师,感觉找到真爱了。。。
2.1 简介
八锁问题即关于锁的八个问题,主要考察synchronized
同步方法的锁的对象问题。
2.2 问题详解
- 主程序
public static void main(String[] args) { Number number = new Number(); new Thread(()->{number.one();},"A").start(); new Thread(()->{number.two();},"B").start(); }
- 八个问题
- 两个普通同步方法,两个线程,标准打印。
结果:class Number{ public synchronized void one() {System.out.println("One");} public synchronized void two() {System.out.println("Two");} }
两者是同一把锁(number对象),所以顺序输出。One Two
- 新增 Thread.sleep() 给 one()
结果:class Number{ public synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public synchronized void two(){ System.out.println("Two"); } }
两者是同一把锁(number对象),所以还是顺序输出。One Two
- 新增普通方法 three()
结果:class Number{ public synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public synchronized void two(){ System.out.println("two"); } public void three(){ System.out.println("Three"); } }
Three One Two
Three
方法不是同步方法,所以先输出(时间短) - 两个普通同步方法,两个 Number 对象
主程序public static void main(String[] args) { Number number1 = new Number(); Number number2 = new Number(); new Thread(()->{number1.one();},"A").start(); new Thread(()->{number2.two();},"B").start(); }
结果class Number{ public synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public synchronized void two(){ System.out.println("two"); } }
两把锁,线程B快,所以先打印TwoTwo One
- 修改 two() 为静态同步方法
结果class Number{ public synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public static synchronized void two(){ System.out.println("two"); } }
静态同步方法的锁为类本身(Two One
Number.class
),所以是两把锁 - 修改两个方法均为静态同步方法
结果:class Number{ public static synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public static synchronized void two(){ System.out.println("two"); } }
两个方法都是静态同步方法,锁都是Number类本身,所以是同一把锁。One Two
- 一个静态同步方法,一个非静态同步方法,两个 Number 对象
主程序public static void main(String[] args) { Number number1 = new Number(); Number number2 = new Number(); new Thread(()->{number1.one();},"A").start(); new Thread(()->{number2.two();},"B").start(); }
结果class Number{ public synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public static synchronized void two(){ System.out.println("two"); } }
Two One
- 两个静态同步方法,两个 Number 对象?
主程序public static void main(String[] args) { Number number1 = new Number(); Number number2 = new Number(); new Thread(()->{number1.one();},"A").start(); new Thread(()->{number2.two();},"B").start(); }
结果class Number{ public static synchronized void one(){ try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("One"); } public static synchronized void two(){ System.out.println("two"); } }
两个方法都是静态同步方法,锁都是Number类本身,所以是同一把锁,与谁调用无关。One Two
- 两个普通同步方法,两个线程,标准打印。