Java并发原理学习笔记+总结+实战(6)——可重入锁

Java中常用的重入锁

    java中重入锁的定义是指可重复、递归调用的锁,在得到同一个对象或类的前提下,外层使用锁之后,在内层中依然可是使用且不会发生死锁。其中最常见的关键字是synchronize和reentrantLock这两个。

使用synchronize实现

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class MyLock implements Lock {

  private boolean isLocked = false;

  private Thread lockBy = null;

  private int lockCount = 0;

  @Override
  public synchronized void lock() {
    // ...

    Thread currentThread = Thread.currentThread(); // Thread-0

    while (isLocked && currentThread != lockBy) {
      try {
        wait();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    isLocked = true;
    lockBy = currentThread;
    lockCount++; // 1   2
  }

  @Override
  public synchronized void unlock() {
    if (lockBy == Thread.currentThread()) {
      lockCount--;  // 1  0

      if (lockCount == 0) {
        notify();
        isLocked = false;
      }
    }
  }

  @Override
  public void lockInterruptibly() throws InterruptedException {

  }

  @Override
  public boolean tryLock() {
    return false;
  }

  @Override
  public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
    // TODO Auto-generated method stub
    return false;
  }



  @Override
  public Condition newCondition() {
    // TODO Auto-generated method stub
    return null;
  }

}

 

public class Sequence {

  private MyLock lock = new MyLock();

  private int value;

  public int getNext() {
    lock.lock();
    value++;
    lock.unlock();
    return value;

  }

  public static void main(String[] args) {

    Sequence s = new Sequence();

    new Thread(new Runnable() {

      @Override
      public void run() {
        while (true) {
          System.out.println(s.getNext());
        }
      }
    }).start();
    new Thread(new Runnable() {

      @Override
      public void run() {
        while (true) {
          System.out.println(s.getNext());
        }
      }
    }).start();
    new Thread(new Runnable() {

      @Override
      public void run() {
        while (true) {
          System.out.println(s.getNext());
        }
      }
    }).start();
    new Thread(new Runnable() {

      @Override
      public void run() {
        while (true) {
          System.out.println(s.getNext());
        }
      }
    }).start();
    new Thread(new Runnable() {

      @Override
      public void run() {
        while (true) {
          System.out.println(s.getNext());
        }
      }
    }).start();
  }

}

    当第一个线程执行getNext()方法,得到了锁,使lockBy等于当前线程,也就是说,执行的这个方法的线程获得了这个锁,每次while循环都会对lockCount变量加一,即当前获得锁的数量加一;当线程调用unlock()释放锁后,lockCount变量减一,当释放了所有的锁之后,才执行notify()方法唤醒线程。如果在执行这个方法时,有第二个线程想要执行这个方法,因为lockBy不等于该线程,导致第二个线程进入了循环,不断执行wait()方法。只有当第一个线程释放了所有的锁,并执行了notify()方法后,第二个线程才被唤醒,继续执行。这就是可重入锁的特点。

你可能感兴趣的:(Java并发原理)