zoukankan      html  css  js  c++  java
  • 多线程学习 公平锁和非公平锁

      公平与非公平锁:锁lock分为 公平锁和非公平锁,公平锁表示现场获取锁的顺序是按照线程加锁的顺序来分配的,

    即先来先得的FIFO先进先出顺序。而非公平锁就是一种获取锁的抢占机制,是随机获得的锁的,和公平锁不一样的就是先来

    不一定先得到锁,这个方式可能造成某些线程一直拿不到锁。

      

      首先来验证公平锁:创建service方法,使用lock进行锁定。

      

    public class Service {
    
    	private ReentrantLock lock;
    	public Service(boolean isFair){
    		super();
    		System.out.println(isFair);
    		lock=new ReentrantLock(isFair);
    	}
    	
    	public void serviceMethod(String str){
    		try {
    			lock.lock();
    			if("a".equals(str)){//将启动的线程全部阻塞在此
    				try {
    					Thread.sleep(2000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			System.out.println("ThreadName= "+Thread.currentThread().getName()+" 获得了锁");
    		} finally {
    			lock.unlock();
    		}
    	}
    }
    

      然后运行验证:

    public class Run {
    
    	public static void main(String[] args) throws InterruptedException {
    
    		
    			fair(true);
    //			fair(false);
    	}
    	
    	public static void fair(boolean  isFair) throws InterruptedException{
    		final Service service=new Service(isFair);
    		
    		new Thread(new Runnable() {
    			public void run() {
    				System.out.println("第一个线程,起阻塞后面线程作用");
    				service.serviceMethod("a");
    			}
    		}).start();
    		
    		Thread.sleep(500);
    		
    		
    		Runnable runnable=new  Runnable() {
    			public void run() {
    				System.out.println("线程 "+Thread.currentThread().getName()+" 运行了");
    				service.serviceMethod("b");
    			}
    		};
    		
    		Thread [] threads=new Thread[10];
    		for (int i = 0; i < threads.length; i++) {
    			threads[i]=new Thread(runnable);
    		}
    		
    		for (int i = 0; i < threads.length; i++) {
    			threads[i].start();
    		}
    		
    		
    	}
    }
    

      公平锁控制台:

    true
    第一个线程,起阻塞后面线程作用
    线程 Thread-1 运行了
    线程 Thread-2 运行了
    线程 Thread-3 运行了
    线程 Thread-4 运行了
    线程 Thread-5 运行了
    线程 Thread-6 运行了
    线程 Thread-7 运行了
    线程 Thread-8 运行了
    线程 Thread-9 运行了
    线程 Thread-10 运行了
    ThreadName= Thread-0 获得了锁
    ThreadName= Thread-1 获得了锁
    ThreadName= Thread-2 获得了锁
    ThreadName= Thread-3 获得了锁
    ThreadName= Thread-4 获得了锁
    ThreadName= Thread-5 获得了锁
    ThreadName= Thread-7 获得了锁
    ThreadName= Thread-6 获得了锁
    ThreadName= Thread-8 获得了锁
    ThreadName= Thread-9 获得了锁
    ThreadName= Thread-10 获得了锁
    

      可以发现,控制台是有序的,其中0线程是为了方便观看,特意增加,将所有的线程阻塞在此。

    非公平锁的控制台:

    false
    第一个线程,起阻塞后面线程作用
    线程 Thread-1 运行了
    线程 Thread-3 运行了
    线程 Thread-2 运行了
    线程 Thread-4 运行了
    线程 Thread-5 运行了
    线程 Thread-10 运行了
    线程 Thread-9 运行了
    线程 Thread-8 运行了
    线程 Thread-7 运行了
    线程 Thread-6 运行了
    ThreadName= Thread-0 获得了锁
    ThreadName= Thread-2 获得了锁
    ThreadName= Thread-3 获得了锁
    ThreadName= Thread-1 获得了锁
    ThreadName= Thread-4 获得了锁
    ThreadName= Thread-5 获得了锁
    ThreadName= Thread-10 获得了锁
    ThreadName= Thread-9 获得了锁
    ThreadName= Thread-8 获得了锁
    ThreadName= Thread-6 获得了锁
    ThreadName= Thread-7 获得了锁
    

      可以发现,先进但不是先获得锁,是无序的。ReentranReentrantLock默认是非公平的

      顺便留下几个lock中常用的方法:

      lock.getHoldCount(); 查询当前线程保持此锁定的个数。也就是调用lock()方法的次数。

      lock.getQueuelength();返回正在等待获取次锁定的线程估计数。例如五个线程,1一个线程正在制定await()方法,name咋动用此方法后返回4.

      lock.getWaitQueueLength(Condition,condition); 返回等待与此锁定相关的给定条件Condition的线程估计数。比如有五个线程执行同一个condition对象的await()方法,

    调用此方法之后返回5.  

      

      每一个优秀的人,都有一段沉默的时光,不抱怨,不诉苦,最后度过那段感动自己的日子。

  • 相关阅读:
    codeforces 719A:Vitya in the Countryside
    POJ3233 Matrix Power Series
    codevs1409 拦截导弹2
    BZOJ1562 [NOI2009]变换序列
    POJ1325 Machine Schedule
    codeforces 715B:Complete The Graph
    BZOJ1972:[SDOI2010]猪国杀
    浅谈模拟
    BZOJ2548:[CTSC2002]灭鼠行动
    BZOJ1033:[ZJOI2008]杀蚂蚁
  • 原文地址:https://www.cnblogs.com/hrlizhi/p/9496411.html
Copyright © 2011-2022 走看看