• Lock的公平锁与非公平锁


    注:lock是可重入锁

    lock锁分为两类:公平锁和非公平锁。按照本人的理解,公平锁指的是在多个线程同时获取锁时,会按照该线程的请求先后顺序来决定哪个线程优先获取到锁(即:根据同步队列中的线程顺序来决定),非公平锁则是自由竞争,和线程的等待时间无关。

    而且非公平锁可能出现一个线程连续获取锁的现象(原因是当一个线程请求锁时,只要获取了同步状态即成功获取锁。在这个前提下,刚释放的线程再次获取同步状态的几率非常大)

    package com.zhl.practice;
    
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author Holley
     * @Description 公平锁与非公平锁的演示
     * @create 2019-05-16 10:16
     **/
    public class LockTest {
    
        private static ReenTrantLock2 fairLock = new ReenTrantLock2(true);
    
        private static ReenTrantLock2 nonfairLock = new ReenTrantLock2(false);
    
        @Test
        public void fair(){
            testLock(fairLock);
        }
    
        @Test
        public void unfair(){
            testLock(nonfairLock);
        }
    
        private void testLock(ReenTrantLock2 lock){
            for(int i = 0; i<5;i++){
                Job job = new Job(lock);
                job.start();
            }
        }
    
        private static class Job extends Thread{
    
            private ReenTrantLock2 lock;
    
            public Job(ReenTrantLock2 lock){
                this.lock = lock;
            }
    
            @Override
            public void run() {
                lock.lock();
                System.out.println("当前线程:" + this.getName() + "等待线程:" + lock.getQueuedThreads().toString());
                lock.unlock();
                lock.lock();
                System.out.println("当前线程:" + this.getName() + "等待线程:" + lock.getQueuedThreads().toString());
                lock.unlock();
            }
        }
        private static class ReenTrantLock2 extends ReentrantLock{
            public ReenTrantLock2(Boolean flag){
                super(flag);
            }
    
            public Collection<Thread> getQueuedThreads(){
    //            System.out.println(super.getQueuedThreads());
                List<Thread> list = new ArrayList<>(super.getQueuedThreads());
                return list;
            }
        }
    
    }

     【注意】thread.start()方法与thread.run()方法的区别是:start()方法会创建一条新的线程,而run()方法则只是thread的一个普通方法,代码案例可见:https://blog.csdn.net/xinbumi/article/details/89918628

  • 相关阅读:
    呀?这就是锁(二)?
    呀?这就是锁(一)?
    线程的建立
    Mybatis基础使用简介
    使用apache+tomcat+mod_jk.so实现集群
    HttpClient使用详解
    HttpClient基础用法
    Collection集合学习(二)———List接口与具体实现
    Docker学习总结(二)—— 镜像,容器
    Docker学习总结(一)—— namespace,cgroup机制
  • 原文地址:https://www.cnblogs.com/zhlblogs/p/10874793.html
Copyright © 2020-2023  润新知