lock锁

package com.shujia.day19.sellTickets4;

import java.util.concurrent.locks.ReentrantLock;

/*
    使用Runnable的方式实现

    为了模拟更加真实的售票情况,我们加入延迟
    问题:
        我们加入了延迟之后,发现
        a. 有重复售卖同一张票的情况(原因1)
        b. 还出现了一个不该出现的票数据,比如第0张票,第-1张票(原因2)
    原因:
        1. cpu小小的时间片,足以让程序执行很多次
        2. 线程的执行具有随机性,且是抢占式执行的

    现象:线程不安全的现象
        如何判断一个程序是否存在线程不安全的现象呢?
        三要素(同时满足):
            1、是否存在多线程环境?
            2、是否存在共享数据?
            3、是否存在多条语句操作着共享数据?
    如何解决线程不安全的现象?
        1、同步代码块
        2、lock锁

    解决方案1:加入同步代码块
        synchronized(对象){
            操作共享数据的代码
        }
      这里的对象,可以是任意一个new出来的对象,但是要保证多个线程之间是同一个对象。

    synchronized的使用:
        1、同步代码块 - 锁对象 - 任意一个对象,前提是多个线程对象共享一个
        2、同步方法 - 锁对象 - this
        3、同静态方法 - 锁对象 - 当前类的class文件对象


    解决方案2:lock锁,利用ReentrantLock类创建锁对象,要求多个线程对象共享一个
        不需要考虑锁对象是谁了。


 */
class Window implements Runnable {
    private static int tickets = 100;
    //    private Object object = new Object();
    private ReentrantLock lock = new ReentrantLock();


    @Override
    public void run() {
        while (true) {
            lock.lock(); // 加锁
            if (tickets > 0) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 正在出售第 " + (tickets--) + " 张票......");
            }
            lock.unlock(); // 释放锁
        }
    }
}

public class SellTicketDemo1 {
    public static void main(String[] args) {
        Window window = new Window();

        Thread w1 = new Thread(window, "窗口1");
        Thread w2 = new Thread(window, "窗口2");
        Thread w3 = new Thread(window, "窗口3");

        w1.start();
        w2.start();
        w3.start();

    }
}
posted @ 2024-08-19 22:11  ていせい  阅读(2)  评论(0编辑  收藏  举报