什么是公平和非公平::
    公平指的是按照线程的请求顺序,来分配锁;非公平指的是不完全按照请求的顺序,在一定情况下,可以插队
    注意::非公平也同样不提倡“插队”行为,这里的非公平指的是“在合适的时机”插队,而不是盲目插队
    什么时机合适呢? 火车票被插队的例子 ,自己没准备好买票,上个买票的人回来又问了一句就有了,不影响我正常买票

    为什么要有非公平锁?
    1. 这样做提高了效率 2. 避免唤醒带来的空档期

    公平的情况(以ReentrantLock为例)
    如果在创建ReentrantLock对象时,参数填写为true,那么这就是个公平锁,否则是非公平锁
    假设线程1234是按顺序调用lock( )的

    注意:
    针对tryLock()方法,它不遵守设定的公平规则;
    例如,当有线程执行tryLock()的时候,一旦有线程释放了锁,那么这个正在执行tryLock的线程就能获取到锁,即使在它之前已经有其他正在等待队列的线程

    1. public class FairLock {
    2. // 例子:公平锁,先竞争锁,只有其中一个假设线程4能拿到锁,其他的都只能排队,排队位置在标记(1),当线程4进入临界区后然后
    3. // 随机休眠,当休眠完毕后离开临界区,打印等待队列长度9,因为总共10个线程,线程4出队。排队的第一个线程3进入第一个临界区,但是
    4. // 之前排队的线程没有离开临界区,所以只能等其他的线程打印完后,才能轮到线程4执行第二个临界区代码,线程3离开临界区,打印等待队列
    5. // 长度也是9,因为线程4在第二个临界区等待,进入了等待队列。当都执行完离开第一个临界区后,在第二个临界区最开始等待的线程4开始打印
    6. // 第二个临界区代码
    7. // 非公平锁:可以进行插队,随拿到锁就先执行
    8. public static void main(String[] args) {
    9. PrintQueue printQueue = new PrintQueue();
    10. Thread[] threads = new Thread[10];
    11. for (int i = 0; i < threads.length; i++) {
    12. new Thread(()->{
    13. System.out.println(Thread.currentThread().getName()+"开始打印");
    14. printQueue.printJob();
    15. System.out.println(Thread.currentThread().getName()+"打印完毕");
    16. }).start();
    17. }
    18. }
    19. // 公平锁,拿不到锁的线程就进行排队,
    20. private static ReentrantLock queueLock = new ReentrantLock(true);
    21. static class PrintQueue{
    22. public void printJob(){
    23. // (1) 被阻塞的线程在此排队
    24. System.out.println("===================>"+queueLock.getQueueLength());
    25. queueLock.lock();
    26. try {
    27. long duration = (long)(Math.random()*6000);
    28. System.out.println(Thread.currentThread().getName()+"正在打印GG, 需要"+(duration/1000)+"秒");
    29. Thread.sleep(duration);
    30. } catch (InterruptedException e) {
    31. e.printStackTrace();
    32. } finally {
    33. queueLock.unlock();
    34. }
    35. System.out.println("========********===========>"+queueLock.getQueueLength());
    36. queueLock.lock();
    37. try {
    38. long duration = (long)(Math.random()*6000);
    39. System.out.println(Thread.currentThread().getName()+"正在打印, 需要"+(duration/1000));
    40. Thread.sleep(duration);
    41. } catch (InterruptedException e) {
    42. e.printStackTrace();
    43. } finally {
    44. queueLock.unlock();
    45. }
    46. }
    47. }
    48. }
    49. /** 公平锁
    50. * Thread-0开始打印
    51. * Thread-4开始打印
    52. * ===================>0
    53. * Thread-1开始打印
    54. * Thread-3开始打印
    55. * ===================>0
    56. * Thread-2开始打印
    57. * ===================>0
    58. * Thread-9开始打印
    59. * ===================>0
    60. * Thread-5开始打印
    61. * ===================>3
    62. * Thread-8开始打印
    63. * ===================>4
    64. * ===================>2
    65. * Thread-7开始打印
    66. * ===================>6
    67. * Thread-6开始打印
    68. * ===================>7
    69. * ===================>0
    70. * Thread-4正在打印GG, 需要4秒
    71. * ========********===========>9
    72. * Thread-3正在打印GG, 需要3秒
    73. * ========********===========>9
    74. * Thread-2正在打印GG, 需要2秒
    75. * ========********===========>9
    76. * Thread-0正在打印GG, 需要0秒
    77. * ========********===========>9
    78. * Thread-5正在打印GG, 需要3秒
    79. * ========********===========>9
    80. * Thread-8正在打印GG, 需要1秒
    81. * ========********===========>9
    82. * Thread-9正在打印GG, 需要2秒
    83. * ========********===========>9
    84. * Thread-7正在打印GG, 需要2秒
    85. * ========********===========>9
    86. * Thread-6正在打印GG, 需要1秒
    87. * ========********===========>9
    88. * Thread-1正在打印GG, 需要3秒
    89. * ========********===========>9
    90. * Thread-4正在打印, 需要2
    91. * Thread-4打印完毕
    92. * Thread-3正在打印, 需要5
    93. * Thread-3打印完毕
    94. * Thread-2正在打印, 需要1
    95. * Thread-2打印完毕
    96. * Thread-0正在打印, 需要5
    97. * Thread-0打印完毕
    98. * Thread-5正在打印, 需要4
    99. * Thread-5打印完毕
    100. * Thread-8正在打印, 需要5
    101. * Thread-8打印完毕
    102. * Thread-9正在打印, 需要5
    103. * Thread-9打印完毕
    104. * Thread-7正在打印, 需要1
    105. * Thread-7打印完毕
    106. * Thread-6正在打印, 需要0
    107. * Thread-6打印完毕
    108. * Thread-1正在打印, 需要4
    109. * Thread-1打印完毕
    110. */