多把不相干的锁

一间大屋子有两个功能:睡觉、学习,互不相干。
现在小南要学习,小女要睡觉,但如果只用一间屋子(一个对象锁)的话,那么并发度很低
解决方案是准备多个房间(多个对象锁)

  1. public class ClassRoom {
  2. public void sleep() throws InterruptedException {
  3. synchronized (this){
  4. System.out.println("sleeping 2小时");
  5. Thread.sleep(2000);
  6. }
  7. }
  8. public void study() throws InterruptedException {
  9. synchronized (this){
  10. System.out.println("studying 1小时");
  11. Thread.sleep(2000);
  12. }
  13. }
  14. }

但这样存在的问题是,不仅多个线程不能同时睡觉,连一个线程睡觉一个线程学习也无法做到,因为锁的是同一个对象,粒度过大。
更好的解决方案是,一个方法锁住一个对象即可。

  1. public class ClassRoom {
  2. private final Object studyRoom =new Object();
  3. private final Object bedRoom = new Object();
  4. public void sleep() throws InterruptedException {
  5. synchronized (studyRoom){
  6. System.out.println("sleeping 2小时");
  7. Thread.sleep(2000);
  8. }
  9. }
  10. public void study() throws InterruptedException {
  11. synchronized (bedRoom){
  12. System.out.println("studying 1小时");
  13. Thread.sleep(2000);
  14. }
  15. }
  16. }

好处与坏处

  • 可以增加并发度,使得不同线程可以实现睡觉与学习同时执行
  • 如果一个线程需要获得多把锁,容易发生死锁现象