# 2、Lock接口

# 1、synchronized关键字

# 1、卖票小程序

package com.hjc;

public class Main {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        }, "张三").start();

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

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

class Ticket {
    private Integer number = 30;

    //卖票接口
    public synchronized void sale() {
        if (number > 0) {
            number--;
            System.out.println(Thread.currentThread().getName() + "卖了第一张票剩余" + number + "张票");
        }

    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 2、lock接口

# 1、lock下的实现类

image-20240107215005400

# 1、ReentrantLock(可重入锁)

可重入锁就是当前线程获取到锁,在当前线程中可以再次获取到该线程的锁而不会出现死锁现象

synchronized与ReentrantLock都是可重入锁

ReentrantLock实现买票小程序

package com.hjc;

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

public class LockStudy {
    public static void main(String[] args) {
        LTicket ticket = new LTicket();
        new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        }, "张三").start();

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

        new Thread(() -> {
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        }, "王五").start();
    }
}
class LTicket {
    private Integer number = 30;

    //使用重入锁
    public final ReentrantLock reentrantLock = new ReentrantLock();

    //卖票接口
    public  void sale() {
        //加可重入锁
        reentrantLock.lock();
        try {
            if (number > 0) {
                number--;
                System.out.println(Thread.currentThread().getName() + "卖了第一张票剩余" + number + "张票");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //解锁可重入锁
            reentrantLock.unlock();
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 2、synchronized与lock区别

1、synchronized会自动获取锁和释放锁,lock不会自动获取或释放,都需要手动

2、synchronized发生异常会自动释放锁,lock如果没有try...catch...finally异常处理,即没有执行unlock方法,则会出现死锁

3、lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去

4、通过lock可以知道有没有成功获取锁,而synchronized无法办到

5、lock可以提高多个线程进行读操作的效率

6、如果竞争的资源比较强,lock的性能远高于synchronized

上次更新: 2024/4/13