公平锁与非公平锁及其测试

公平锁与非公平锁 

公平锁:获取锁的先后顺序与请求锁的先后顺序保持一致,具有FIFO特点。

非公平锁:反之则为非公平锁。

什么是可重入?

同一个线程重复多次获取同一把锁,释放的时候也需要释放多次。

Java中锁的特点

  • synchronized:可重入,非公平(不可设置)。锁的是Object对象

  • ReentrantLock:可重入,公平或非公平(可设置)。通过获取同步状态来获取锁,并非通过设置Object对象头来获取锁。

公平锁测试

package concurrent.ReentrantLock;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @基本功能:测试公平锁和非公平锁
 * @program:summary
 * @author:peicc
 * @create:2019-10-08 13:11:50
 **/
public class FairAndUnfairTest {
    private static Lock fairLock=new ReentrantLock2(true);// 公平锁
    private static Lock unfairLock=new ReentrantLock2(false);// 非公平锁
    private static CountDownLatch count=new CountDownLatch(1);
    private static class Job extends Thread{
        private Lock lock;
        public Job(Lock lock) {
            this.lock=lock;
        }
        @Override
        public void run() {
            try {
                count.await();
            }
            catch (InterruptedException e) {
            }
            for (int i = 0; i <2 ; i++) {
                lock.lock();
                try {
                    System.out.print("Lock by ["+getName()+ "], Waiting by [" /*+ ((ReentrantLock2) lock).getQueuedThreads()*/);
                    ArrayList<Thread> list=(ArrayList<Thread>) ((ReentrantLock2) lock).getQueuedThreads();
                    for (int j = 0; j <list.size() ; j++) {
                        System.out.print(list.get(j).getName()+",");
                    }
                    System.out.println("]");
                } finally {
                    lock.unlock();
                }

            }
        }
    }
    private static void testLock(Lock lock){
        for (int i = 0; i <5 ; i++) {
            Thread thread=new Job(lock);
            thread.setName(""+i);
            thread.start();
        }
        count.countDown();
    }
    /*********
     *内部类
     */
    private static class ReentrantLock2 extends ReentrantLock{
        /***
         * @函数功能:构造函数
         * @param fair:
         * @return:
         */
        public ReentrantLock2(boolean fair){
            super(fair);
        }

        @Override
        public Collection<Thread> getQueuedThreads() {
            List<Thread> list=new ArrayList<>(super.getQueuedThreads());
            Collections.reverse(list);
            return list;
        }
    }

    public static void main(String[] args) {
        System.out.println("-------------------公平锁测试-----------------");
        testLock(fairLock);
       /* System.out.println("-------------------非公平锁测试-----------------");
        testLock(unfairLock);*/
    }

}

 运行结果

-------------------公平锁测试-----------------
Lock by [2], Waiting by [3,]
Lock by [3], Waiting by [1,0,]
Lock by [1], Waiting by [0,3,2,]
Lock by [0], Waiting by [3,2,1,4,]
Lock by [3], Waiting by [2,1,4,0,]
Lock by [2], Waiting by [1,4,0,]
Lock by [1], Waiting by [4,0,]
Lock by [4], Waiting by [0,]
Lock by [0], Waiting by [4,]
Lock by [4], Waiting by []

可以看出,公平锁获取锁的顺序是严格按照请求顺序的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章