什么是公平锁,什么是非公平锁?
公平锁是指按照线程的请求顺序去加锁;
非公平锁是指不完全按照线程的请求顺序进行加锁,一定情况下是允许插队的。
线程唤醒的开销比较大,使用非公平锁可以避免线程唤醒带来的空档期而导致资源的浪费。
下面进行公平锁和非公平锁的代码演示,请看下代码
package com.yang.lock;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 公平锁和非公平锁代码演示
* cnxieyang@163.com
*/
public class FairLock {
public static void main(String[] args) {
PrintQueue printQueue = new PrintQueue();
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(new Job(printQueue));
}
for (int i=0;i<10;i++){
threads[i].start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Job implements Runnable{
private PrintQueue printQueue;
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始打印");
printQueue.printDocument(new Object());
System.out.println(Thread.currentThread().getName()+"打印结束");
}
}
class PrintQueue {
//公平锁
private Lock queueLock = new ReentrantLock(true);
public void printDocument(Object document) {
queueLock.lock();
try {
int duration =new Random().nextInt(10)+1;
System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
Thread.sleep(duration*1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
//打印两份
queueLock.lock();
try {
int duration =new Random().nextInt(10)+1;
System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
Thread.sleep(duration*1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
}
}
执行结果如下所示:
Thread-0开始打印 Thread-0正在执行文件打印操作,需要10 Thread-1开始打印 Thread-2开始打印 Thread-3开始打印 Thread-4开始打印 Thread-5开始打印 Thread-6开始打印 Thread-7开始打印 Thread-8开始打印 Thread-9开始打印 Thread-1正在执行文件打印操作,需要9 Thread-2正在执行文件打印操作,需要3 Thread-3正在执行文件打印操作,需要6 Thread-4正在执行文件打印操作,需要2 Thread-5正在执行文件打印操作,需要1 Thread-6正在执行文件打印操作,需要8 Thread-7正在执行文件打印操作,需要1 Thread-8正在执行文件打印操作,需要3 Thread-9正在执行文件打印操作,需要6 Thread-0正在执行文件打印操作,需要10 Thread-0打印结束 Thread-1正在执行文件打印操作,需要2 Thread-1打印结束 Thread-2正在执行文件打印操作,需要9 Thread-2打印结束 Thread-3正在执行文件打印操作,需要5 Thread-3打印结束 Thread-4正在执行文件打印操作,需要8 Thread-4打印结束 Thread-5正在执行文件打印操作,需要4 Thread-5打印结束 Thread-6正在执行文件打印操作,需要5 Thread-6打印结束 Thread-7正在执行文件打印操作,需要1 Thread-7打印结束 Thread-8正在执行文件打印操作,需要3 Thread-8打印结束 Thread-9正在执行文件打印操作,需要9 Thread-9打印结束 Process finished with exit code 0
非公平锁实例代码
package com.yang.lock;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 公平锁和非公平锁代码演示
* cnxieyang@163.com
*/
public class FairLock {
public static void main(String[] args) {
PrintQueue printQueue = new PrintQueue();
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(new Job(printQueue));
}
for (int i=0;i<10;i++){
threads[i].start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Job implements Runnable{
private PrintQueue printQueue;
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始打印");
printQueue.printDocument(new Object());
System.out.println(Thread.currentThread().getName()+"打印结束");
}
}
class PrintQueue {
//非公平锁
private Lock queueLock = new ReentrantLock(false);
public void printDocument(Object document) {
queueLock.lock();
try {
int duration =new Random().nextInt(10)+1;
System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
Thread.sleep(duration*1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
//打印两份
queueLock.lock();
try {
int duration =new Random().nextInt(10)+1;
System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
Thread.sleep(duration*1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
}
}
运行结果如下所示:
Thread-0开始打印 Thread-0正在执行文件打印操作,需要7 Thread-1开始打印 Thread-2开始打印 Thread-3开始打印 Thread-4开始打印 Thread-5开始打印 Thread-6开始打印 Thread-7开始打印 Thread-8开始打印 Thread-9开始打印 Thread-0正在执行文件打印操作,需要9 Thread-0打印结束 Thread-1正在执行文件打印操作,需要1 Thread-1正在执行文件打印操作,需要5 Thread-1打印结束 Thread-2正在执行文件打印操作,需要8 Thread-2正在执行文件打印操作,需要3 Thread-2打印结束 Thread-3正在执行文件打印操作,需要10 Thread-3正在执行文件打印操作,需要6 Thread-3打印结束 Thread-4正在执行文件打印操作,需要3 Thread-4正在执行文件打印操作,需要4 Thread-4打印结束 Thread-5正在执行文件打印操作,需要1 Thread-5正在执行文件打印操作,需要8 Thread-5打印结束 Thread-6正在执行文件打印操作,需要5 Thread-6正在执行文件打印操作,需要2 Thread-6打印结束 Thread-7正在执行文件打印操作,需要8 Thread-7正在执行文件打印操作,需要4 Thread-7打印结束 Thread-8正在执行文件打印操作,需要6 Thread-8正在执行文件打印操作,需要8 Thread-8打印结束 Thread-9正在执行文件打印操作,需要7 Thread-9正在执行文件打印操作,需要6 Thread-9打印结束 Process finished with exit code 0
从上数两个代码的运行结果中,我们可以公平锁和非公平锁的差异。
tryLock不遵守排队,可以进行插队。
原文:https://www.cnblogs.com/cnxieyang/p/12755530.html