手写一个公平锁
何为公平锁:
线程的运行,根据线程的提交(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();
}
}

浙公网安备 33010602011771号