注意:Synchronized是同一把锁
Lock是不同的锁,但是解锁必须一一对应。

可重入锁(递归锁)

Synchronized

  1. public class Demo01 {
  2. public static void main(String[] args) {
  3. Phone phone = new Phone();
  4. new Thread(()->{
  5. phone.sms();
  6. },"A").start();
  7. new Thread(()->{
  8. phone.sms();
  9. },"B").start();
  10. }
  11. }
  12. class Phone{
  13. public synchronized void sms(){
  14. System.out.println(Thread.currentThread().getName() + "sms");
  15. call(); // 这里也有锁
  16. }
  17. public synchronized void call(){
  18. System.out.println(Thread.currentThread().getName() + "call");
  19. }
  20. }

Lock 版

  1. import java.util.concurrent.locks.Lock;
  2. import java.util.concurrent.locks.ReentrantLock;
  3. public class Demo02 {
  4. public static void main(String[] args) {
  5. Phone2 phone = new Phone2();
  6. new Thread(()->{
  7. phone.sms();
  8. },"A").start();
  9. new Thread(()->{
  10. phone.sms();
  11. },"B").start();
  12. }
  13. }
  14. class Phone2{
  15. Lock lock = new ReentrantLock();
  16. public void sms(){
  17. lock.lock(); // 细节问题:lock.lock(); lock.unlock(); // lock 锁必须配对,否则就会死在里面
  18. lock.lock();
  19. try {
  20. System.out.println(Thread.currentThread().getName() + "sms");
  21. call(); // 这里也有锁
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. } finally {
  25. lock.unlock();
  26. lock.unlock();
  27. }
  28. }
  29. public void call(){
  30. lock.lock();
  31. try {
  32. System.out.println(Thread.currentThread().getName() + "call");
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. } finally {
  36. lock.unlock();
  37. }
  38. }
  39. }