• 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 适合锁大量的同步代码
  • 相关阅读:
    bzoj3832
    bzoj2117
    bzoj1095
    BZOJ 4247: 挂饰 题解
    1296: [SCOI2009]粉刷匠
    3163: [Heoi2013]Eden的新背包问题
    2287: 【POJ Challenge】消失之物
    1334: [Baltic2008]Elect
    2748: [HAOI2012]音量调节
    1606: [Usaco2008 Dec]Hay For Sale 购买干草
  • 原文地址:https://www.cnblogs.com/blackBlog/p/13451368.html
Copyright © 2020-2023  润新知