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

 更新时间:2021年08月27日 13:23:04   作者:最好的硕硕  
这篇文章主要为大家详细介绍了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();
    t2.start();
    t3.start();

}

1.1 局部加锁

public class MyThread extends Thread{
 
 private static int ticket = 1000;
 private static Object obj = new Object();
 
 public MyThread(String name) {
  super(name);
 }

 @Override
 public void run() {
  
  while(ticket > 0){
   synchronized(obj){
    if(ticket > 0){
     System.out.println(Thread.currentThread().getName() + "正在销售第" +(1001-ticket)+ "张票");
     ticket--;
    }
    if(ticket <= 0){
     System.out.println(Thread.currentThread().getName() + "票已售罄");
    }
   }
  }
 }
}

1.2 方法加锁

public class MyThread extends Thread{
 
 private static int ticket = 1000;
 
 public MyThread(String name) {
  super(name);
 }

 @Override
 public void run() {
  
  while(ticket > 0){
   method02();
  }
 }
 
 //锁对象:类的字节码文件对象(MyThread.class),有static修饰
 public static synchronized void method02(){
  if(ticket > 0){
   System.out.println(Thread.currentThread().getName() + "正在销售第" +(1001-ticket)+ "张票");
   ticket--;
  }
  if(ticket <= 0){
   System.out.println(Thread.currentThread().getName() + "票已售完");
  }
 }
}

1.3 手动加锁

public class MyThread extends Thread{
 
 private static int ticket = 1000;
 private static Lock lock = new ReentrantLock();
 
 public MyThread(String name) {
  super(name);
 }

 @Override
 public void run() {
  
  while(ticket > 0){
   lock.lock();//手动上锁
   if(ticket > 0){
    System.out.println(Thread.currentThread().getName() + "正在销售第" +(1001-ticket)+ "张票");
    ticket--;
   }
   if(ticket <= 0){
    System.out.println(Thread.currentThread().getName() + "票已售完");
   }
   lock.unlock();//手动解锁
  }
 }
}

2 任务类

测试方法:

public static void main(String[] args) {
    Task task = new Task();
    Thread t1 = new Thread(task, "窗口1");
    Thread t2 = new Thread(task, "窗口2");
    Thread t3 = new Thread(task, "窗口3");
    t1.start();
    t2.start();
    t3.start();

}

2.1 局部加锁

public class Task implements Runnable{
 private int tickets=1000;

 @Override
 public void run() {
  while(tickets>0){
   synchronized (this) {
    if(tickets > 0)
             {
                 System.out.printf ("%s窗口正在售出第%d张票\n",Thread.currentThread().getName(),1001-tickets);
                 tickets--;
             }
             if(tickets<=0){
              System.out.printf("%s窗口售罄\n",Thread.currentThread().getName());
             }
   }
   
  } 
 } 
}

2.2 方法加锁

public class Task implements Runnable{
 private int tickets=1000;

 @Override
 public void run() {
  while(tickets>0){
   method();  
  } 
 } 
    //方法加锁,没有使用static修饰
 public synchronized void method(){
  if(tickets > 0)
        {
            System.out.printf ("%s窗口正在售出第%d张票\n",Thread.currentThread().getName(),1001-tickets);
            tickets--;
        }
        if(tickets<=0){
         System.out.printf("%s窗口售罄\n",Thread.currentThread().getName());
        }
 }
}

2.3 手动加锁

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

public class Task implements Runnable{
 private int tickets=1000;
 private Lock lock =new  ReentrantLock();
 @Override
 public void run() {
  while(tickets>0){ 
   lock.lock();//手动上锁
   if(tickets > 0)
            {
                System.out.printf ("%s窗口正在售出第%d张票\n",Thread.currentThread().getName(),1001-tickets);
                tickets--;
            }
            if(tickets<=0){
             System.out.printf("%s窗口售罄\n",Thread.currentThread().getName());
            }
            lock.unlock();//手动关锁
  } 
 } 
}

效果截图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java多线程之间日志traceId传递方式

    Java多线程之间日志traceId传递方式

    这篇文章主要介绍了Java多线程之间日志traceId传递方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • SpringBoot整合Web开发之文件上传与@ControllerAdvice

    SpringBoot整合Web开发之文件上传与@ControllerAdvice

    @ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理。对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不止于此
    2022-08-08
  • 使用Lombok子类继承父类,父类属性不生效问题及解决

    使用Lombok子类继承父类,父类属性不生效问题及解决

    在使用Lombok库时,若子类继承父类,父类的属性可能不会自动生效,为解决此问题,可通过在父类上添加@Getter和@Setter注解,或使用@SuperBuilder注解来确保父类属性在子类中有效,同时,需注意确保Lombok版本一致且正确配置了相关插件
    2024-10-10
  • spring 项目实现限流方法示例

    spring 项目实现限流方法示例

    这篇文章主要为大家介绍了spring项目实现限流的方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • SpringBoot超详细深入讲解底层原理

    SpringBoot超详细深入讲解底层原理

    我们知道springboot内部是通过spring框架内嵌Tomcat实现的,当然也可以内嵌jetty,undertow等等web框架;另外springboot还有一个特别重要的功能就是自动装配,这又是如何实现的呢
    2022-07-07
  • 使用easyexcel导出的excel文件,使用poi读取时异常处理方案

    使用easyexcel导出的excel文件,使用poi读取时异常处理方案

    这篇文章主要介绍了使用easyexcel导出的excel文件,使用poi读取时异常处理方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 总结java多线程之互斥与同步解决方案

    总结java多线程之互斥与同步解决方案

    文中总结了线程互斥与同步,synchronized使用细节及原理,Reentrylock使用细节等知识,对解决Java多线程互斥与同步等问题很有效,,需要的朋友可以参考下
    2021-05-05
  • Java 详解循环屏障CyclicBarrier如何实现多线程分段等待执行完成

    Java 详解循环屏障CyclicBarrier如何实现多线程分段等待执行完成

    CyclicBarrier是一个同步工具类,可以翻译成循环屏障,也叫障碍器或同步屏障。CyclicBarrier内部有一个计数器count,调用障碍器的await方法会使计数器count的值减一,当计数器count的值为0时,表明调用了await方法线程已经达到了设置的数量
    2021-11-11
  • Java8学习教程之lambda表达式语法介绍

    Java8学习教程之lambda表达式语法介绍

    众所周知lambda表达式是JAVA8中提供的一种新的特性,它支持Java也能进行简单的“函数式编程”。 下面这篇文章主要给大家介绍了关于Java8学习教程之lambda表达式语法的相关资料,需要的朋友可以参考下。
    2017-09-09
  • Java字符串相关类使用方法详解

    Java字符串相关类使用方法详解

    String、StringBuilder、StringBuffer还傻傻分不清,下面这篇文章主要给大家介绍了关于Java字符串相关类使用的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-07-07

最新评论