Skip to content
DAILY QUOTE

“ ”

传统Synchronized锁

来看一个多线程卖票例子

java
public class SaleTicketTDemo01 {
    /*
     * 真正的多线程开发,公司中的开发,降低耦合性
     * 线程就是一个单独的资源类,没有任何附属的操作!
     * 1、 属性、方法
     */
    public static void main(String[] args) {
        //并发:多个线程同时操作一个资源类,把资源类丢入线程
        Ticket ticket = new Ticket();
        // @FunctionalInterface 函数式接口,jdk1.8 lambada表达式
        new Thread(() -> {
            for (int i = 1; i < 50; i++) {
                ticket.sale();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 1; i < 50; i++) {
                ticket.sale();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 1; i < 50; i++) {
                ticket.sale();
            }
        }, "C").start();
    }
}
//资源类 OOP
class Ticket {
    //属性、方法
    private int number = 50;
    // 卖票的方式
    // synchronized 本质: 队列,锁
    public synchronized void sale() {
        if (number > 0) {
            System.out.println(Thread.currentThread().getName() + "卖出了" + (50-(--number)) + "张票,剩余:" + number + "张票");
        }
    }
}

Lock接口

公平锁:十分公平:可以先来后到

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

java
public class SaleTicketTDemo02 {
    public static void main(String[] args) {
        //并发:多个线程同时操作一个资源类,把资源类丢入线程
        Ticket2 ticket = new Ticket2();
        // @FunctionalInterface 函数式接口,jdk1.8 lambada表达式
        new Thread(() -> {
            for (int i = 1; i < 50; i++) {
                ticket.sale();
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 1; i < 50; i++) {
                ticket.sale();
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 1; i < 50; i++) {
                ticket.sale();
            }
        }, "C").start();
    }
}
//Lock 3步骤
// 1. new ReentrantLock();
// 2. lock.lock()  加锁
// 3. lock.unlock() 解锁
class Ticket2 {
    //属性、方法
    private int number = 50;
    Lock lock = new ReentrantLock();
    // 卖票方式
    public void sale() {
        lock.lock();// 加锁
        try {
            // 业务代码
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了" +
                        (50 - (--number)) + "张票,剩余:" + number + "张票");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();// 解锁
        }
    }
}

Synchronized和Lock区别

  1. Synchronized 内置的Java关键字,Lock 是一个java类

  2. Synchronized 无法判断获取锁的状态,Lock 可以判断是获取到了锁

  3. Synchronized 会自动释放锁,Lick 必须要手动释放锁!如果不释放就会 死锁

  4. Synchronized 线程1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock 锁就不一定会等待下去

  5. Synchronized 可重入锁,不可以中段的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置)

  6. Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!