003 ReentrantLock之公平锁、非公平锁

概念:如果一个锁是公平的,那么锁的获取顺序,就应该符合请求的绝对时间顺序。即是说等待锁的队列中,排在队列最前面的那个线程将最先获得锁。如果一个锁是非公平的,那么则不要求锁的获取顺序一定严格遵循请求时间的顺序。

一、非公平锁实验设计;

1、充塞20个线程获取非公平锁;

2、在线程中打印当前线程名称和等待锁的线程列表;

3、待20个线程执行完毕,观察当前线程名称与等待锁的线程列表顺序是否一致;

4、代码如下:

public class FairAndUnFairLockTest {
	
	public static void main(String[] args) {
		FairAndUnFairLock lock = new FairAndUnFairLock(false);
		for(int i = 0; i < 20; i++){
			new Job(i+"", lock).start();
		}
	}
	
	static class FairAndUnFairLock extends ReentrantLock{
		
		public FairAndUnFairLock(boolean fair) {
			super(fair);
		}
		
		public List<Thread> getQueuedThreads(){
			List<Thread> list = new ArrayList<Thread>(super.getQueuedThreads());
			Collections.reverse(list);
			return list;
		}
	}
	
	static class Job extends Thread{
		
		private FairAndUnFairLock lock;
		
		public Job(String name, FairAndUnFairLock fairLock) {
			super(name);
			this.lock = fairLock;
		}

		@Override
		public void run() {
			
			lock.lock();
			
			try{
				for(int i = 0; i < 1; i++){
					System.out.print(Thread.currentThread().getName() + " obtain lock, ");
					for(Thread thread : lock.getQueuedThreads()){
						System.out.print(thread.getName()+" ");
					}
					System.out.print("wating lock.");
					System.out.println();
				}
			}
			finally{
				lock.unlock();
			}
		}
		
	}
}

5、实验结果如下:

等待锁的线程的顺序为1 2 3 4 5 6…线程,真实获得锁的线程的顺序为0 11 16 1 2…

这两者的顺序不一致,说明非公平锁的获取顺序并不符合请求的绝对时间的顺序。

二、公平锁实验设计;

1、充塞20个线程获取公平锁;

2、在线程中打印当前线程名称和等待锁的线程列表;

3、待20个线程执行完毕,观察当前线程名称与等待锁的线程列表顺序是否一致;

4、代码如下:

public class FairAndUnFairLockTest {
	
	public static void main(String[] args) {
		FairAndUnFairLock lock = new FairAndUnFairLock(true);
		for(int i = 0; i < 20; i++){
			new Job(i+"", lock).start();
		}
	}
	
	static class FairAndUnFairLock extends ReentrantLock{
		
		public FairAndUnFairLock(boolean fair) {
			super(fair);
		}
		
		public List<Thread> getQueuedThreads(){
			List<Thread> list = new ArrayList<Thread>(super.getQueuedThreads());
			Collections.reverse(list);
			return list;
		}
	}
	
	static class Job extends Thread{
		
		private FairAndUnFairLock lock;
		
		public Job(String name, FairAndUnFairLock fairLock) {
			super(name);
			this.lock = fairLock;
		}

		@Override
		public void run() {
			
			lock.lock();
			
			try{
				for(int i = 0; i < 1; i++){
					System.out.print(Thread.currentThread().getName() + " obtain lock, ");
					for(Thread thread : lock.getQueuedThreads()){
						System.out.print(thread.getName()+" ");
					}
					System.out.print("wating lock.");
					System.out.println();
				}
			}
			finally{
				lock.unlock();
			}
		}
		
	}
}

5、实验结果;

等待锁的线程的顺序为1 2 3 5 4 6 7,真实获得锁的线程的顺序为0 1 2 3 5 4 6 7,两者顺序一致,说明公平锁的获取是严格遵循线程请求锁的绝对时间的顺序的。

三、备忘;

1、ReentrantLock有公平锁、非公平锁的实现;

2、new ReentrantLock()默认是位非公平锁;

3、非公平锁的性能,是远大于公平锁的。除非必要,否则应优先非公平锁的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值