并发编程之买票问题

简介: 该博客文章通过Java代码示例演示了在没有锁和使用公平锁、非公平锁的情况下,多线程环境下对共享资源的访问控制,以及不同锁机制对线程访问顺序的影响。

这里使用 ambda表达式(参数)->{代码}

首先是没有锁的情况下多个线程争夺同一个资源的情况

package com.zheng;


//线程就是一个单独的资源类
public class BuyTicket {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        //并发:多线程操作同一个资源类,把资源类丢入线程
        //lambda表达式(参数)->{代码}
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        },"C").start();
    }
}


//资源类
 class Ticket{
    //属性和方法
    private int num = 20;

    public void sale(){
        if(num > 0){
            System.out.println(Thread.currentThread().getName()+"卖出了"+(num--)+"票,剩余:"+num);
        }
    }

 }

测试结果
在这里插入图片描述

在这里插入图片描述
公平锁:谁先来谁先执行
非公平锁:可以插队(默认)

加锁后

package com.zheng;


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

//线程就是一个单独的资源类
public class BuyTicket {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        //并发:多线程操作同一个资源类,把资源类丢入线程
        //lambda表达式(参数)->{代码}
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 30; i++) {
                ticket.sale();
            }
        },"C").start();
    }
}


//资源类
 class Ticket{
    //属性和方法
    private int num = 20;

    Lock lock = new ReentrantLock();

    public void sale(){
        lock.lock();//加锁
        try {
            //业务代码
            if(num > 0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(num--)+"票,剩余:"+num);
            }
        } catch (Exception e) {
            lock.unlock();
        }
    }

 }

在这里插入图片描述

相关文章
|
5月前
多线程卖票问题
多线程卖票问题
|
6月前
|
安全 Java 程序员
惊呆了!Java多线程里的“synchronized”竟然这么神奇!
【6月更文挑战第20天】Java的`synchronized`关键字是解决线程安全的关键,它确保同一时间只有一个线程访问同步代码。在案例中,`Counter`类的`increment`方法如果不加同步,可能会导致竞态条件。通过使用`synchronized`方法或语句块,可以防止这种情况,确保线程安全。虽然同步会带来性能影响,但它是构建并发应用的重要工具,平衡同步与性能是使用时需考虑的。了解并恰当使用`synchronized`,能有效应对多线程挑战。
21 1
|
7月前
|
Java API
【并发编程】吃透Synchronized
【并发编程】吃透Synchronized
33 1
|
7月前
|
安全 C语言
每天一道C语言编程:排队买票
每天一道C语言编程:排队买票
62 0
|
7月前
|
存储 安全 算法
Java并发之舞:掌握线程同步的精髓
Java并发之舞:掌握线程同步的精髓
71 0
Java并发之舞:掌握线程同步的精髓
|
7月前
|
Java
深入理解Java中的并发编程:线程与锁的奥秘
【4月更文挑战第2天】本文将深入探讨Java并发编程的核心概念,包括线程和锁。我们将详细解析线程的生命周期,以及如何通过锁来保证数据的一致性和同步。此外,我们还将讨论一些常见的并发问题,如死锁、活锁和饥饿,以及如何解决这些问题。
|
7月前
|
Java
java多线程售票例子
java多线程售票例子
|
7月前
|
安全 Java
java多线程之Lock锁原理以及案例实现电影院卖票
java多线程之Lock锁原理以及案例实现电影院卖票
|
Java
线程同步经典案例——卖票问题
用上面这种方式创建的所有线程都共享同一份数据,但如果用第一种创建线程的方式,则要将数据用static修饰才能共享
146 0
线程同步经典案例——卖票问题
|
缓存 算法 Java
多线程:第一章:我(线程)这一生
多线程:第一章:我(线程)这一生
135 0
多线程:第一章:我(线程)这一生