手写一个公平锁

何为公平锁:

  线程的运行,根据线程的提交(start() 方法的调用时间点),依次执行。

公平锁实现的原理:

  1、使用链表来维护数据。(方便获取头节点)

  2、当一个线程过来,就创建一个节点,节点中存放的内容为,wait()的对象。

  3、当上一个线程结束,则获取头节点,获取节点中存放的对象,调用对象的notify()方法,唤醒正在等待的线程。

  4、移除已经唤醒了的节点数据。

  重点:每一个线程的wait方法,都使用对应的对象来调用。一个线程维护一个相应的对象。

代码示例:  

/**
 * 手写一个公平锁
 */
public class MyFair {

  private boolean islock;
  private Thread lockThread;
  /**
   * 先用list代替一下双端链表
   */
  private List<WaitNotifyNode> waitThreads = new ArrayList<>();

  public void lock() {
    //如果被锁,表示有线程正在运行。
    while (islock) {
      WaitNotifyNode wnn = new WaitNotifyNode();
      synchronized (this) {
        waitThreads.add(wnn);
      }
      wnn.waitThread(); //wait方法,仅仅释放监视锁,而不会释放上层锁(即:lock方法,如果加锁,则会一直锁定。)
    }
    islock = true;
  }

  public void unLock() {
    islock = false;
    System.out.println(Thread.currentThread().getName() + ",unlock");
    synchronized (this) {
      if (waitThreads.size() > 0) {
        waitThreads.get(0).notifyThread();
        waitThreads.remove(0);
      }
    }
  }

  public static void main(String[] args) {
    MethodFair mf = new MethodFair();
    new Thread( () ->  mf.a(), "thread-1").start();
    new Thread( () ->  mf.a(), "thread-2").start();
  }
}

class MethodFair {
  MyFair myFair = new MyFair();
  public void a() {
    myFair.lock();
    System.out.println(Thread.currentThread().getName() + ",A");
    try {
      Thread.sleep(500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + ",end!");
    myFair.unLock();
  }
}

/**
 * wait,notify线程类
 */
class WaitNotifyNode {
  public synchronized void waitThread() {
    try {
      this.wait();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  public synchronized void notifyThread() {
    this.notify();
  }
}

  

原文地址:https://www.cnblogs.com/chen--biao/p/11361594.html