ReentrantLock锁
ReentrantLock是可重入锁,并且可以实现公平锁。Sychronized是可重入锁、非公平锁。
话不多说,上demo:
1 package com.example.demo.util; 2 3 import java.util.concurrent.locks.ReentrantLock; 4 5 public class ReetrantLockFairTest { 6 7 // 参数为true,则为公平锁,即线程按等待时间顺序,最久的先获得锁 8 // 参数为false或为空则为非公平锁,线程自由竞争锁 9 static ReentrantLock lock = new ReentrantLock(true); 10 11 public static void main(String[] args) { 12 13 for (int i = 0; i < 8; i++) { 14 new Thread(() -> test(), "线程" + i).start(); 15 } 16 } 17 18 public static void test() { 19 20 for (int i = 0; i < 2; i++) {// 使用循环2轮并且加sleep时间,来模拟测试线程执行顺序 21 lock.lock(); 22 try { 23 System.out.println(Thread.currentThread().getName() + ":获得了锁。"); 24 Thread.sleep(500l);// 模拟时间需确保第一个线程获得锁后,其他所有线程都已经启动并等待锁。然后进入for循环等待第二轮 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } finally { 28 lock.unlock(); 29 } 30 } 31 } 32 }
执行结果:可以看到,第二轮获得锁的线程顺序与第一轮 一样。这样就实现了公平锁。
线程0:获得了锁。
线程2:获得了锁。
线程1:获得了锁。
线程3:获得了锁。
线程4:获得了锁。
线程5:获得了锁。
线程6:获得了锁。
线程7:获得了锁。
线程0:获得了锁。
线程2:获得了锁。
线程1:获得了锁。
线程3:获得了锁。
线程4:获得了锁。
线程5:获得了锁。
线程6:获得了锁。
线程7:获得了锁。