Java多线程之简单模拟售票功能

一、创建

二、完整代码

package com.ql;

import lombok.SneakyThrows;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class Mythread extends Thread {
    public Mythread(String name) {
        super(name);
    }

    @SneakyThrows
    @Override
    public void run() {
        for (; ; ) {
            //锁的状态是默认是打开状态
            //获取锁的状态
            int lockStatus = this.findLockStatus();
            if (lockStatus == 0) {
                //修改锁的状态 =>>锁定
                this.locked();
                //获取总票数
                int tickets = this.findTickets();
                //剩余票数
                int i = this.remainVotes();
                //判断票数
                if (tickets < 1) {
                    //已售卖完 跳出循环
                    break;
                } else {
                    //卖一张票
                    int remainVotes = this.saleOneTicket();
                    System.out.println(this.getName() + "当前的票数:" + tickets);
                    System.out.println(this.getName() + "售票后:" + remainVotes);
                    //  释放锁
                    this.unlock();
                }
            }
        }

    }

    /**
     * 剩余票数
     *
     * @return
     * @throws IOException
     */
    private int remainVotes() throws IOException, InterruptedException {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://localhost:8080/lock/remainVotes").build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();

        String string = response.body().string();
        int ticketsVote = Integer.parseInt(string);
        return ticketsVote;
    }

    /**
     * 释放锁
     */
    private void unlock() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://localhost:8080/lock/unlock").build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
    }

    /**
     * 卖票一张
     */
    private int saleOneTicket() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://localhost:8080/lock/saleOneTicket").build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        String string = response.body().string();
        int remainVotes = Integer.parseInt(string);
        return remainVotes;
    }

    /**
     * 获取锁的状态
     */
    private int findLockStatus() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://localhost:8080/lock/findLock").build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        String string = response.body().string();
        int lockStatus = Integer.parseInt(string);
        return lockStatus;
    }

    /**
     * 修改锁状态
     */
    private int locked() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://localhost:8080/lock/locked").build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        String string = response.body().string();

        int lockStatus = Integer.parseInt(string);
        return lockStatus;
    }

    /**
     * 查看总票数
     *
     * @throws IOException
     */
    private int findTickets() throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url("http://localhost:8080/lock/findTickets").build();
        Call call = okHttpClient.newCall(request);
        Response response = call.execute();
        String string = response.body().string();
        Integer tickets = Integer.parseInt(string);
        return tickets;
    }
}
package com.ql;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/lock")
public class ClientService {
    /**
     * 总票数
     */
    private static Integer tickets = 100;

    /**
     * 锁的状态 0:未锁   1:锁
     */
    private static Integer lockStatus = 0;

    /**
     * 卖票
     */
    @RequestMapping("/saleOneTicket")
    public Integer saleOneTicket() {
        return tickets = tickets - 1;
    }

    /**
     * 查看总票数
     */
    @RequestMapping("/findTickets")
    public Integer findTickets() {
        return tickets;
    }

    /**
     * 查看锁的状态
     */
    @RequestMapping("/findLock")
    public synchronized Integer findLock() {
        Integer lock=lockStatus;
        //改变锁状态,使线程串行执行
        this.locked();
        return lock;
    }

    /**
     * 改变锁状态
     */
    @RequestMapping("/locked")
    public synchronized int locked() {
        //更改锁的状态为1(上锁),避免多个线程同时获取锁的状态都为0(未上锁),从而导致线程安全问题
        lockStatus = 1;
        return lockStatus;
    }

    /**
     * 释放锁
     */
    @RequestMapping("/unlock")
    public synchronized int unlock() {
        return lockStatus = 0;
    }

    /**
     * 剩余票数
     *
     * @return
     */
    @RequestMapping("/remainVotes")
    public int remainVotes() {

        return tickets;
    }

}

三、流程图解析

到此这篇关于Java多线程之简单模拟售票功能的文章就介绍到这了,更多相关Java模拟售票功能内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 如何用Java模拟XN*2图灵机

    题目描述: 对于XN*2图灵机进行模拟,任意给定的十进制数,转换为收缩扩展二进制的编码,再编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果.用C或C++或Java或Python语言实现程序解决问题. 要求:1. 程序风格良好(使用自定义注释模板): 2. 提供友好的输入输出,并进行输入数据的正确性验证. 算法分析: 1. 将十进制数转换为二进制数: 2. 将二进制数转换为收缩扩展二进制的编码: 3. 根据当前的内态和输入执行XN*2图灵机的指令: 4. 将结果的二进制编码

  • Java多线程模拟售票程序和线程安全问题

    Java中线程部分知识中,售票程序非常经典.程序中也有一些问题存在! 需求:模拟3个窗口同时在售100张票. 问题1:为什么100张票被卖出了300张票? 原因:因为tickets是非静态的,非静态的成员变量数据是在每个对象中都会维护一份数据的,三个线程对象就会有三份. 解决方案:把tickets票数共享出来给三个线程对象使用.使用static修饰. 问题2: 出现了线程安全问题 ? 线程安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的. java线程同步机制的方式: 方式一:同

  • Java多线程模拟电影售票过程

    用多线程模拟电影售票过程(Java实训) 实训目的: 多线程的实现.线程同步 实训要求: 总票数和售票窗口数由键盘输入,用每个线程处理一个窗口的售票. Test.java package program5; import java.util.Scanner; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc=new Scanner(S

  • 使用Java程序模拟实现新冠病毒传染效果

    简单介绍 2020年注定是不平凡的一年,新冠肺炎肆虐全球,传染性特别强,目前全球感人人数还在逐渐攀升,作为中华儿女特别感谢政府作出的努力,非常感谢并致敬医护人员,是他们的努力为我们创造安全的环境,向你们致敬! 模拟方案 以下是程序粗略的模拟病毒传染过程,具体方案如下: 首先需要构造一个200 * 200的格子界面有四种不同的颜色状态标记着程序执行的过程程序执行10次,初始化格子也就是0的时候,需要在整个格子最中心的100个格子标记为红色,剩余数据随机抽取四千(且不能重复)标记为黑色,其余没有标记

  • Java 实现模拟用户登录的示例代码

    创建一个用户类类型的集合,手动输入用户库 主要是判定输入的用户名和密码是否与库中的匹配 做好区别是用户名输入错误还是密码输入错误的提示. 定义用户类 public class User{ String username; String keyword; public User(String username, String keyword) { this.username = username; this.keyword = keyword; } } 主程序 import java.util.A

  • 使用java一维数组模拟压栈弹栈

    思路 先进后出,优先解决压栈的问题,之后解决弹栈和main方法 功能 随时模拟压栈 随时模拟弹栈 防止异常和各种错误 随时可以遍历"栈"中存在的变量的方法,压栈弹栈栈帧清晰可见! 使用演示: 压栈: 栈满检测: 遍历栈内存和栈帧: 只要栈中有变量就会输出栈帧: 弹栈: 栈空检测:(没有变量,栈帧不输出!) 源码: import java.util.Scanner; public class MoveTest01 { //局部变量供栈方法的遍历数组使用 static int i; //创

  • JAVA模拟新增顺序表及单链表

    最近在回顾大学学的数据结构,这里给大家用java模拟顺序表和单链表的新增 1顺序表新增 /** * 顺序表 * * @author cjd * */ public class ArrayList { private Object[] elementData; // 底层是一个数组,目前还没有确定长度 private int size; // 不是数组分配了几个空间,而是元素的个数 public ArrayList() { this(4); } public ArrayList(int initi

  • java多线程之火车售票系统模拟实例

    1.前言 为了学习多线程共享与通信,我们模拟一个火车售票系统,假设有10张火车票,三个窗口(也就是三个线程)同时进行售票. 2.非同步代码 package com.tl.skyLine.thread; /** * Created by tl on 17/3/6. */ public class SellTicket { public static void main(String[] args) { TicketWindow tw = new TicketWindow(); Thread t1

  • Java多线程之简单模拟售票功能

    一.创建 二.完整代码 package com.ql; import lombok.SneakyThrows; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import java.io.IOException; public class Mythread extends Thread { public Mythread(String name)

  • Java实现的简单数字时钟功能示例

    本文实例讲述了Java实现的简单数字时钟功能.分享给大家供大家参考,具体如下: 应用名称:Java数字时钟 用到的知识:Java GUI编程,线程 开发环境:win8+eclipse+jdk1.8 功能说明:可以显示当前系统的年月日.星期以及准确时间,并实时更新显示. 效果图: 源代码: import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.BorderLayout; import javax.swing.JL

  • JAVA NIO实现简单聊天室功能

    本文实例为大家分享了JAVA NIO实现简单聊天室功能的具体代码,供大家参考,具体内容如下 服务端 初始化一个ServerSocketChannel,绑定端口,然后使用Selector监听accept事件. 当有accept发生时,表示有客户端连接进来了,获取客户端的SocketChannel,然后注册其read事件:用来接收客户端发送的消息. package chatroom; import java.io.IOException; import java.net.InetSocketAddr

  • java web实现简单登录注册功能全过程(eclipse,mysql)

    目录 1.工程文件 2.DBBean.java 3.login.jsp 4.check.jsp 5.zhuce.jsp 6.zhuceck.jsp 7.success.jsp 8.zhucesu.jsp 9.数据库创造 总结 1.工程文件 基本的文件布局,没使用任何css文件,就是简单实现登录注册,页面没有做任何美化: 使用的是MySQL8.0.12,8一下的mysql链接代码有微小差别,网上教程基本都是8一下的,随便找找就能找到: 2.DBBean.java package Bean; imp

  • java web实现简单留言板功能

    本文实例为大家分享了java web实现简单留言板的具体代码,供大家参考,具体内容如下 一.目标 用户可以登录并记住密码进入留言板,添加留言,点击留言列表中的标题可显示该条留言全部内容. 二.相关知识 1.使用Cookie实现自动登录 用户第一次登录网站,服务器将用户名和密码以Cookie的形式发送到客户端.当客户之后再次访问该网站时,浏览器自动将Cookie文件中的用户名和密码随请求一起发送到服务器,服务器从Cookie中取出用户名和密码并且通过验证. 2.java类的定义与使用 定义java

  • java Socket实现简单模拟HTTP服务器

    最近复习计算机网络,复习完应用层之后对于理论知识还是没有一个深刻的概念,索性就动手用Java Socket API 模拟做一个HTTP服务器,巩固一下应用层的知识. HTTP基于TCP协议,协议采用了请求/响应模型.客户端向服务器发送一个请求,请求头包含请求的方法.URL.协议版本.以及包含请求修饰符.客户信息和内容的类似于MIME的消息结构.服务器以一个状态行作为响应,响应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息.实体元信息以及可能的实体内容--百度百科. 话不多说,还是直

  • java 多线程交通信号灯模拟过程详解

    这学期我们java课程的课程设计项目----交通信号灯的线程设计 实验目的:多线程设计,同步机制 题意 设计一个交通信号灯类: 变量:位置.颜色(红.黄.绿).显示时间(秒). 方法:切换信号灯. 创建并启动两个线程(东西向.南北向)同时运行. 实验要求 设计线程. 设计路口信号灯示意图界面. 进一步将每个方向的信号灯分成3种车道灯:左转.直行和右转. 根据车流量进行时间的模糊控制. 在课程设计的开始并没有仔细看老师的要求,只知道是交通信号灯.然后就开始各种找资料,百度,网上大量的关于红绿灯的设

  • java多线程模拟实现售票功能

    铁道部发布了一个售票任务,要求销售1000张票,要求有3个窗口来进行销售,请编写多线程程序来模拟这个效果. 1 线程类 测试方法: public static void main(String[] args) { MyThread t1 = new MyThread("窗口1"); MyThread t2 = new MyThread("窗口1"); MyThread t3 = new MyThread("窗口1"); t1.start(); t

  • java多线程模拟抢红包功能

    今天有朋友问我一道面试题,有5个人抢5个红包,可重复抢,用多线程程序实现,实现方式有多种,分享一下我的思路:应用了阻塞队列的特性. /** * Created by zhanglinqiang on 2016/6/23. */ public class MyTest { public static void main(String[] args) throws InterruptedException { LinkedBlockingQueue<LuckyMoney> luckyMoneys

  • Java多线程实现模拟12306火车站售票系统

    该系统一共涉及到3个类: 车票(Ticket) 12306系统(System12306) 售票窗口(Window) 车票类,涉及三个属性: 起始站 终点站 票价 public class Ticket { //起始站 private String startStation; //终点站 private String destination; /**POJO对象,它里面的基本类型最好使用包装类 * 因为如果如果该类用来装从数据库中读取的信息 * 如果读取出null,那么基本类型是无法存null的,

随机推荐