什么是公平和非公平::
公平指的是按照线程的请求顺序,来分配锁;非公平指的是不完全按照请求的顺序,在一定情况下,可以插队
注意::非公平也同样不提倡“插队”行为,这里的非公平指的是“在合适的时机”插队,而不是盲目插队
什么时机合适呢? 火车票被插队的例子 ,自己没准备好买票,上个买票的人回来又问了一句就有了,不影响我正常买票
为什么要有非公平锁?
1. 这样做提高了效率 2. 避免唤醒带来的空档期
公平的情况(以ReentrantLock为例)
如果在创建ReentrantLock对象时,参数填写为true,那么这就是个公平锁,否则是非公平锁
假设线程1234是按顺序调用lock( )的
注意:针对tryLock()方法,它不遵守设定的公平规则;例如,当有线程执行tryLock()的时候,一旦有线程释放了锁,那么这个正在执行tryLock的线程就能获取到锁,即使在它之前已经有其他正在等待队列的线程
public class FairLock {// 例子:公平锁,先竞争锁,只有其中一个假设线程4能拿到锁,其他的都只能排队,排队位置在标记(1),当线程4进入临界区后然后// 随机休眠,当休眠完毕后离开临界区,打印等待队列长度9,因为总共10个线程,线程4出队。排队的第一个线程3进入第一个临界区,但是// 之前排队的线程没有离开临界区,所以只能等其他的线程打印完后,才能轮到线程4执行第二个临界区代码,线程3离开临界区,打印等待队列// 长度也是9,因为线程4在第二个临界区等待,进入了等待队列。当都执行完离开第一个临界区后,在第二个临界区最开始等待的线程4开始打印// 第二个临界区代码// 非公平锁:可以进行插队,随拿到锁就先执行public static void main(String[] args) {PrintQueue printQueue = new PrintQueue();Thread[] threads = new Thread[10];for (int i = 0; i < threads.length; i++) {new Thread(()->{System.out.println(Thread.currentThread().getName()+"开始打印");printQueue.printJob();System.out.println(Thread.currentThread().getName()+"打印完毕");}).start();}}// 公平锁,拿不到锁的线程就进行排队,private static ReentrantLock queueLock = new ReentrantLock(true);static class PrintQueue{public void printJob(){// (1) 被阻塞的线程在此排队System.out.println("===================>"+queueLock.getQueueLength());queueLock.lock();try {long duration = (long)(Math.random()*6000);System.out.println(Thread.currentThread().getName()+"正在打印GG, 需要"+(duration/1000)+"秒");Thread.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();} finally {queueLock.unlock();}System.out.println("========********===========>"+queueLock.getQueueLength());queueLock.lock();try {long duration = (long)(Math.random()*6000);System.out.println(Thread.currentThread().getName()+"正在打印, 需要"+(duration/1000));Thread.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();} finally {queueLock.unlock();}}}}/** 公平锁* Thread-0开始打印* Thread-4开始打印* ===================>0* Thread-1开始打印* Thread-3开始打印* ===================>0* Thread-2开始打印* ===================>0* Thread-9开始打印* ===================>0* Thread-5开始打印* ===================>3* Thread-8开始打印* ===================>4* ===================>2* Thread-7开始打印* ===================>6* Thread-6开始打印* ===================>7* ===================>0* Thread-4正在打印GG, 需要4秒* ========********===========>9* Thread-3正在打印GG, 需要3秒* ========********===========>9* Thread-2正在打印GG, 需要2秒* ========********===========>9* Thread-0正在打印GG, 需要0秒* ========********===========>9* Thread-5正在打印GG, 需要3秒* ========********===========>9* Thread-8正在打印GG, 需要1秒* ========********===========>9* Thread-9正在打印GG, 需要2秒* ========********===========>9* Thread-7正在打印GG, 需要2秒* ========********===========>9* Thread-6正在打印GG, 需要1秒* ========********===========>9* Thread-1正在打印GG, 需要3秒* ========********===========>9* Thread-4正在打印, 需要2* Thread-4打印完毕* Thread-3正在打印, 需要5* Thread-3打印完毕* Thread-2正在打印, 需要1* Thread-2打印完毕* Thread-0正在打印, 需要5* Thread-0打印完毕* Thread-5正在打印, 需要4* Thread-5打印完毕* Thread-8正在打印, 需要5* Thread-8打印完毕* Thread-9正在打印, 需要5* Thread-9打印完毕* Thread-7正在打印, 需要1* Thread-7打印完毕* Thread-6正在打印, 需要0* Thread-6打印完毕* Thread-1正在打印, 需要4* Thread-1打印完毕*/
