锁是给线程用的,线程拿到锁之后才能干活。当多个线程竞争一个锁时,同一个时间只能有一个线程脱颖而出持有锁,其他线程等该线程释放锁后发起下一轮竞争。那么这种竞争就存在公平性问题,如果是公平的竞争,那么这些线程就得有序来依次得到锁,这就需要线程们按先来后到排队,第一个线程使用完后把锁递给第二个线程,以此类推。非公平的锁是无序的,举个例子:线程甲持有锁,后面线程乙跑过来争,发现被甲拿了就去睡觉(休眠或者被挂起)了,等线程甲释放锁通知乙来取;过了会儿,乙被唤醒时,刚好线程丙半路杀过来了,把锁拿去用了,而乙还在迷糊着,等丙释放锁时乙刚好完全醒了拿到了锁。
从上面可以看到,如果竞争很激烈,锁被持有时间短,那么非公平锁能充分利用时间,公平锁反而因为线程的切换浪费了时间。反之,如果线程持有锁的时间长,那么非公平锁会被频繁请求,线程重试次数多,做了很多无用功,公平锁按部就班传递锁。内置锁只能是非公平的,显式锁可以自己定义,下面看个例子:
package com.wulinfeng.concurrent; import java.util.concurrent.locks.ReentrantLock; public class FairAndUnfairLock { public void doSomething(boolean isFair) { ReentrantLock lock = null; if (isFair) { lock = new ReentrantLock(true); // 公平锁 printThreadInfo(lock); } else { lock = new ReentrantLock(); // 非公平锁 printThreadInfo(lock); } } private void printThreadInfo(ReentrantLock lock) { try { lock.lock(); System.out.println(Thread.currentThread().getName() + "获取锁定."); } finally { lock.unlock(); } } public static void main(String[] args) { final FairAndUnfairLock fairOrUnfair = new FairAndUnfairLock(); Thread[] threadArray = new Thread[20]; System.out.println("非公平锁开始:"); // 非公平锁 for (int i = 0; i < 20; i++) { threadArray[i] = new Thread(new Runnable() { @Override public void run() { fairOrUnfair.doSomething(false); } }, "wulinfeng-" + i); } for (int i = 0; i < 20; i++) { threadArray[i].start(); } // 等非公平锁跑完 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("公平锁开始:"); // 公平锁 for (int i = 0; i < 20; i++) { threadArray[i] = new Thread(new Runnable() { @Override public void run() { fairOrUnfair.doSomething(true); } }, "wulinfeng-" + i); } for (int i = 0; i < 20; i++) { threadArray[i].start(); } } }
输出结果:
非公平锁开始: wulinfeng-11获取锁定. wulinfeng-2获取锁定. wulinfeng-9获取锁定. wulinfeng-6获取锁定. wulinfeng-7获取锁定. wulinfeng-10获取锁定. wulinfeng-1获取锁定. wulinfeng-0获取锁定. wulinfeng-12获取锁定. wulinfeng-8获取锁定. wulinfeng-4获取锁定. wulinfeng-3获取锁定. wulinfeng-5获取锁定. wulinfeng-16获取锁定. wulinfeng-14获取锁定. wulinfeng-13获取锁定. wulinfeng-18获取锁定. wulinfeng-15获取锁定. wulinfeng-17获取锁定. wulinfeng-19获取锁定. 公平锁开始: wulinfeng-1获取锁定. wulinfeng-0获取锁定. wulinfeng-3获取锁定. wulinfeng-5获取锁定. wulinfeng-2获取锁定. wulinfeng-4获取锁定. wulinfeng-6获取锁定. wulinfeng-8获取锁定. wulinfeng-7获取锁定. wulinfeng-14获取锁定. wulinfeng-12获取锁定. wulinfeng-10获取锁定. wulinfeng-9获取锁定. wulinfeng-16获取锁定. wulinfeng-18获取锁定. wulinfeng-11获取锁定. wulinfeng-15获取锁定. wulinfeng-13获取锁定. wulinfeng-17获取锁定. wulinfeng-19获取锁定.
从上面结果看公平锁只能是大致按顺序来。
时间: 2024-10-25 10:56:55