zoukankan      html  css  js  c++  java
  • 手写一个公平锁

    何为公平锁:

      线程的运行,根据线程的提交(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();
      }
    }
    

      

  • 相关阅读:
    矩阵运算(二维数组)
    AndroidManifest.xml
    单位和尺寸
    java Map集合类
    http相关
    文件管理与XMl、JSON解析
    Handler与多线程
    App内容分享
    Fragment以及懒加载
    广播接收器与短信
  • 原文地址:https://www.cnblogs.com/chen--biao/p/11361594.html
Copyright © 2011-2022 走看看