java 多线程 - Lock 锁 - 公平锁和非公平锁

上接:

说明

Lock 锁分为公平锁和非公平锁

公平锁

线程获取锁的顺序是按照加锁的顺序来分配的,即:先来先得,后到的排队

非公平锁

获取锁是 抢占机制,是随机获取锁的,先来的不一定能拿到锁,
有可能一直拿不到锁,所以结果不公平。

效率更高

ReentrantLock 类

默认构造方法使用的是非公平锁,设置公平锁如下:

ReentrantLock lock = new ReentrantLock(true);

例子-非公平锁

package ReentrantLock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class 卖票_非公平锁 implements Runnable {
    Lock lock = new ReentrantLock();
    public final int COUNT=100;
    private int ticket=1;
    @Override
    public void run() {
        while(true){
            try {
                lock.lock(); // 获取锁
                if (ticket > COUNT) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "-售出票号:" + ticket);
                ticket++;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }finally {
                lock.unlock();// 释放锁
            }
        }
    }


    public static void main(String[] args) {
        卖票_非公平锁 ri=new 卖票_非公平锁();
        Thread t1=new Thread(ri,"窗口1");
        Thread t2=new Thread(ri,"窗口2");
        t1.start();
        t2.start();
    }
}

执行结果

窗口1-售出票号:82
窗口1-售出票号:83
窗口1-售出票号:84
窗口1-售出票号:85
窗口2-售出票号:86
窗口2-售出票号:87
窗口2-售出票号:88
窗口2-售出票号:89
窗口2-售出票号:90
窗口2-售出票号:91

非公平锁是 抢占机制,是随机获取锁的,所以可能 窗口1 会一直获取锁,也可能 窗口2 会一直获取到锁

提示:有时,只有窗口1在卖票,窗口2没有机会卖票,需要多执行几次

例子-公平锁

package ReentrantLock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class 卖票_公平锁 implements Runnable {
    Lock lock = new ReentrantLock(true);
    public final int COUNT=100;
    private int ticket=1;
    @Override
    public void run() {
        while(true){
            try {
                lock.lock(); // 获取锁
                if (ticket > COUNT) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "-售出票号:" + ticket);
                ticket++;
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }finally {
                lock.unlock();// 释放锁
            }
        }
    }


    public static void main(String[] args) {
        卖票_公平锁 ri=new 卖票_公平锁();
        Thread t1=new Thread(ri,"窗口1");
        Thread t2=new Thread(ri,"窗口2");
        t1.start();
        t2.start();
    }
}

执行结果

窗口1-售出票号:1
窗口2-售出票号:2
窗口1-售出票号:3
窗口2-售出票号:4
窗口1-售出票号:5
窗口2-售出票号:6
窗口1-售出票号:7

两个窗口交替执行,也就是说:两个线程公平的获取到锁

参考:
https://blog.csdn.net/m0_50370837/article/details/124471888


原文出处:https://malaoshi.top/show_1IX4rqkUfaz9.html