Java之ReentrantLock公平锁和非公平锁

    在Java的ReentrantLock构造函数中提供了两种锁:创建公平锁和非公平锁(默认)。代码如下:

public ReentrantLock() {
       sync = new NonfairSync();
}

 public ReentrantLock(boolean fair) {
       sync = fair ? new FairSync() : new NonfairSync();
}

 

此例可反应公平锁和非公平锁的差异:

package concurrency;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author yuanxu
 * Apr 11, 2017 9:59:24 PM
 */
public class ReentrantLockTest {
    private static final ReentrantLock lock = new ReentrantLock();
    private static final ReentrantLock fairlock = new ReentrantLock(true);
    private int n;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ReentrantLockTest rlt = new ReentrantLockTest();
        for (int i=0; i<100; i++) {
            Thread nonT = new Thread(new NonFairTestThread(rlt));
            nonT.setName("nonFair[" + (i + 1) + "]");
            nonT.start();
            
            Thread fairT = new Thread(new FairTestThread(rlt));
            fairT.setName("fair[" + (i + 1) + "]");
            fairT.start();
        }
    }
    
    static class NonFairTestThread implements Runnable {
        private ReentrantLockTest rlt;
        
        public NonFairTestThread(ReentrantLockTest rlt) {
            this.rlt = rlt;
        }
        
        public void run() {
            lock.lock();
            try {
                rlt.setNum(rlt.getNum() + 1);
                System.out.println(Thread.currentThread().getName()
                        + " nonfairlock***************" + rlt.getNum());
            } finally {
                lock.unlock();
            }
        }
    }
    
    static class FairTestThread implements Runnable {
        private ReentrantLockTest rlt;
        
        public FairTestThread(ReentrantLockTest rlt) {
            this.rlt = rlt;
        }
        
        public void run() {
            fairlock.lock();
            try {
                rlt.setNum(rlt.getNum() + 1);
                System.out.println(Thread.currentThread().getName()
                        + "   fairlock=======" + rlt.getNum() + "   "  
                        + fairlock.getHoldCount() + " queuelength="  
                        + fairlock.getQueueLength());
            } finally {
                fairlock.unlock();
            }
        }
    }
    
    public void setNum(int n) {
        this.n = n;
    }
    
    public int getNum() {
        return n;
    }

}

 

运行结果反映:

在公平的锁上,线程按照他们发出请求的顺序获取锁,但在非公平锁上,则允许‘插队’。

在公平的锁中,如果有另一个线程持有锁或者有其他线程在等待队列中等待这个所,那么新发出的请求的线程将被放入到队列中。而非公平锁上,只有当锁被某个线程持有时,新发出请求的线程才会被放入队列中。

非公平锁性能高于公平锁性能的原因: 在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。

 

参考: 

http://blog.csdn.net/zmx729618/article/details/51593666

http://blog.csdn.net/qq_22929803/article/details/51458340

    原文作者:圆旭
    原文地址: https://www.cnblogs.com/pinganzi/p/6696601.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞