使用synchronized实现Lock

思考:
  1. lock锁是锁住lock() 和unlock()之间的代码,让其变成单线程,所以要想实现一个lock功能,就要想怎么实现这样两个方法
  2. 去填充lock()和unlock()方法要抓住currentThread这个关键方法就可以
  3. 使用synchronized的时候如何让线程等待呢?是用wait()方法。怎么让线程唤醒呢,是用notify()方法。那么就要在lock()方法中使用wait()方法,在unlock()方法中使用notify()方法。那么我们在使用wait()和notify()的时候是有一个条件的,就是currentThread方法
     1 public class MyLock {
     2     private static final long NONE = -1;   //当没有任何线程持有锁时锁的线程ID
     3     private static long owner = NONE;   //区分锁的持有者线程的标志
     4     private static int state;   //锁的状态,使锁具有可重入性
     5     private static long lastThreadId;   //记录上一次持有锁的线程ID,使锁具有可重入性,1是确保线程在重入后解锁的次数和重入次数相同,清空锁的拥有者下次不报异常,2是记录上次线程ID,在锁状态位大于0并且当前线程和上次线程不一致时当前线程要等待,避免锁了10次解锁2次其他线程就进来了
     6     
     7     public synchronized void lock() {
     8         long currentThreadId = Thread.currentThread().getId();
     9         while ((owner != NONE && currentThreadId != owner) || (state > 0 && lastThreadId != currentThreadId)) {
    10             try {
    11                 this.wait();
    12             } catch (InterruptedException e) {
    13                 e.printStackTrace();
    14             }
    15         }
    16         owner = currentThreadId;
    17         lastThreadId = currentThreadId;
    18         state += 1;
    19     }
    20     public synchronized void unclock() {
    21         long currentThreadId = Thread.currentThread().getId();
    22         if ((owner != currentThreadId && lastThreadId != currentThreadId) || --state < 0) {
    23             if (state < 0) {
    24                 state = 0;
    25             }
    26             throw new IllegalThreadStateException();
    27         }
    28         owner = NONE;
    29         lastThreadId = currentThreadId;
    30         this.notifyAll();
    31     }
    32 }

     

posted @ 2022-03-11 00:59  独醉乄  阅读(102)  评论(0)    收藏  举报