2. Lock 锁

Lock 锁(*)

传统 synchronized

package pers.vincent.matrix.subject.juc;

public class JucTest1 {

    public static void main(String[] args) {
        // 获取CPU核数
//        System.out.println(Runtime.getRuntime().availableProcessors());

        // 多个线程操作同一个资源类
        Ticket ticket = new Ticket();
        // 函数式接口 jdk 1.8 lambda 表达式 (参数)->{ 代码块 }
        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        }, "A").start();

        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        }, "B").start();

        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        }, "C").start();
    }

}

class Ticket{
    private int ticketNum = 50;

    // synchronized 的本质:锁和排队
    public synchronized void sale(){
        if(ticketNum>0){
            System.out.println(Thread.currentThread().getName() + "卖出了第" + ticketNum-- + "票, 剩余票数=" + ticketNum);
        }
    }
}

Lock 接口

Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); } 

1.Lock 的实现类

  • ReentrantLock : 可重复锁
  • ReentrantReadWriteLock.ReadLock
  • ReentrantReadWriteLock.WriteLock

ReentrantLock

公平锁:十分公平,先来后到

非公平锁:十分不公平,可以插队(默认

2.Lock 代码实现

package pers.vincent.matrix.subject.juc;

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

public class JUCTest2 {
    public static void main(String[] args) {
        Ticket2 ticket = new Ticket2();
        new Thread(()->{ for (int i = 0; i < 60; i++) ticket.sale(); }, "A").start();

        new Thread(()->{ for (int i = 0; i < 60; i++) ticket.sale(); }, "B").start();

        new Thread(()->{ for (int i = 0; i < 60; i++) ticket.sale(); }, "C").start();

    }
}

// Lock
// 1. new ReentrantLock()
// 2. lock.Lock()
// 3. finally lock.unlock();
class Ticket2{
    private int ticketNum = 50;

    Lock lock = new ReentrantLock();

    public void sale(){

        lock.lock();

        lock.tryLock();// 尝试获取锁

        try {
            if(ticketNum>0){
                System.out.println(Thread.currentThread().getName() + "卖出了第" + ticketNum-- + "票, 剩余票数=" + ticketNum);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
}

synchronized 和 Lock 的区别

  1. Synchronized 内置的 Java 关键字,Lock 是一个Java类
  2. Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
  3. Synchronized 会自动释放锁,Lock 必须手动释放锁,如果不释放,死锁
  4. Synchronized 如果线程1(获得锁,阻塞)、线程2(等待);Lock锁就不一定会等待下去
  5. Synchronized 可重入锁,不可以中断,非公平;Lock 可重入锁,可以判断锁,非公平(可以自己设置)
  6. Synchronized 适合少量的代码同步问题;Lock 适合锁大量的同步代码
posted @ 2020-08-07 10:50  湘北不会输的  阅读(121)  评论(0)    收藏  举报