使用synchronized实现同步控制,并使用wait()和notify()实现线程之间的通信。

编程要求如下:

可售出票的数量为一个固定值(total),从键盘读入。当余票的数量足够出售时(余票数量大于客户购买票数),则先售票;如果没有余票了(票数为0)或余票数量不够了(余票数量小于客户购买票数),则需要等待退票。退票后,如果余票足够出售,则又开始售票。退票规则:有票被售出,才能退票。如果退票数大于已售票总数,也只能退回已售出票的实际数量。比如:已售出3张票,第一次退回了2张票,第2次就只能退1张票了。售票线程正在售票的时候不能退票,反之亦然。

程序包含以下类:

  1. 定义Ticket类(Tickets.java), 表示:票(能售或退)。
  2. 定义一个线程SellTicketThread类,售票线程,模拟多次(题中为3次)售票的操作;
  3. 定义一个线程ReturnTicketThread类,退票线程,模拟多次(题中为3次)退票的操作;
  4. 定义一个测试线程的主类Main.java,分别创建售票和退票的线程对象、启动线程,模拟多次售票和退票的过程。

需补充如下代码,使程序能正常运行:

  1. 为Ticket类补充sellTicket方法和returnTicket方法,两个方法均使用线程同步与通信实现,并将Ticket类补充完整。方法如下:
    synchronized public void sellTicket(int num); //num表示购票数,也就是售出票数
    synchronized public void returnTicket(int num); //num表示退票数

  2. 通过实现Runnable实现SellTicketThread类,编写SellTicketThread类。

  3. 通过实现Runnable实现ReturnTicketThread类,编写ReturnTicketThread类。

答案:

import java.util.Scanner;public class Main {public static void main(String[] args) throws InterruptedException {Scanner sc=new Scanner(System.in);//System.out.println("请输入票数:");int num=sc.nextInt();        //从键盘读入总票数Ticket tickets = new Ticket(num);    //产生票new Thread(new sellTicketThread(tickets)).start();//sellTicketThread售票new Thread(new returnTicketThread(tickets)).start();//returnTicketThread退票Thread.sleep(50);    //休眠等待售票和退票执行完毕System.out.println(tickets.freeNum);}
}class Ticket {int total;        //总票数int freeNum;    //多线程共享变量:余票数量int soldNum;    //已售出票数boolean hasTicket;    //true表示有足够的票出售,false则表示票数不够int count = 3;    //线程售票退票次数int sellNum = 3;    //单次售票数量int returnNum = 2;    //单次退票数量public Ticket(int number) {total = number;freeNum = total;    //售票前:总数与余票数相等soldNum = 0;            //已售出票数hasTicket = (freeNum >= sellNum);    //余票足够}//上面是裁判程序,下面是答案//在下面补充Ticket类的synchronized售票方法synchronized public void sellTicket(int num){//num表示购票数,也就是售出票数while (freeNum < sellNum){//System.out.println("余票不足");try {wait();} catch (InterruptedException e) {e.printStackTrace();}}freeNum-=num;soldNum+=num;System.out.println("售出"+num+"余票"+freeNum);notifyAll();}//在下面补充Ticket类的synchronized退票方法,并将Ticket类补充完整synchronized public void returnTicket(int num){//num表示退票数while(returnNum > soldNum || freeNum >= sellNum){//优先售票//System.out.println("补票过多");{try {wait();} catch (InterruptedException e) {e.printStackTrace();}}}freeNum+=num;soldNum-=num;System.out.println("退回"+num+"余票"+freeNum);notifyAll();}
}
//在下面补充SellTicketThread类,通过实现Runnable实现SellTicketThread类
class sellTicketThread implements Runnable{Ticket tickets;public sellTicketThread() {}public  sellTicketThread(Ticket tickets){this.tickets = tickets;}@Overridepublic void run() {for(int i=0;i<tickets.count;i++)tickets.sellTicket(tickets.sellNum);}
}//在下面补充ReturnTicketThread类,通过实现Runnable实现ReturnTicketThread类
class  returnTicketThread implements Runnable{Ticket tickets;public returnTicketThread(){}public returnTicketThread(Ticket tickets){this.tickets = tickets;}@Overridepublic void run() {for(int i=0;i<tickets.count;i++)tickets.returnTicket(tickets.returnNum);}
}

总结,简单生产者消费者模式的多线程题目,写的时候吧sellNum打成了soldNum改了十来分钟,以后要更细心才行

6-4 多线程编程:使用多线程同步与通信,模拟实现售票系统的售票和退票过程。 (20 分)相关推荐

  1. Win32多线程编程(3) — 线程同步与通信

    一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线程的 ...

  2. Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)

    本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...

  3. 多线程编程、线程同步|安全和线程通信

    多线程编程 多线程的优势 线程在程序中是独立的.并发的执行流,与分隔的进程相比,进程中的线程之间的隔离程度要小.他们共享内存.文件句柄和其他每个进程应有的状态. 因为线程的划分尺度小于进程,使得多线程 ...

  4. java多线程同步与死锁,廖雪峰Java11多线程编程-2线程同步-3死锁

    在多线程编程中,要执行synchronized块,必须首先获得指定对象的锁. 1.Java的线程锁是可重入的锁 public void add(int m){ synchronized (lock){ ...

  5. 多线程编程java_Java多线程编程

    Java给多线程编程提供了内置的支持.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销. ...

  6. python多线程编程_python多线程编程(1): python对多线程的支持

    前面介绍过多线程的基本概念,理解了这些基本概念,掌握python多线程编程就比较容易了. 在开始之前,首先要了解一下python对多线程的支持. 虚拟机层面 Python虚拟机使用GIL(Global ...

  7. 多线程编程 java_java多线程编程

    一.多线程的优缺点 多线程的优点: 1)资源利用率更好 2)程序设计在某些情况下更简单 3)程序响应更快 多线程的代价: 1)设计更复杂 虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般 ...

  8. C++多线程编程以及epoll处理socket通信时多端口问题

    问题根源:当有许多客户端用socket来连接我的服务器(期间存在一定的数据交互)的时候,为了提高性能,我们需要采用多线程编程(处理具体的请求),同时还要使用epoll来高效的在IO事件之间切换(侦查s ...

  9. java多线程编程_Java多线程编程实战指南+设计模式篇.pdf

    Java多线程编程实战指南+设计模式篇.pdf 对Java架构技术感兴趣的工程师朋友们可以关注我,转发此文后私信我"Java"获取更多Java编程PDF资料(附送视频精讲) 关注我 ...

最新文章

  1. 前端三十五:图片的基本概念
  2. WSL(windows subsystem for linux)安装错误:安装过程中遇到错误,但可以继续安装。组件: ‘WSL 内核‘ 错误代码: 0x80072f78解决方法
  3. 根据redis自增生成全局唯一订单id
  4. C++ STL容器总结之vector(超详细版)
  5. H3C防火墙实现NAT+DHCP
  6. 多进程单线程模型与单进程多线程模型之争
  7. Eclipse远程调试HDP源代码
  8. Learning Face Age Progression: A Pyramid Architecture of GANs
  9. [蓝桥杯][基础练习VIP]Huffuman树
  10. ubuntu 18.04桌面版启动错误: Unable to mount root fs on unknown-block(0,0)
  11. 多表查询过滤重复数据_数据分析工具SQL—多表查询
  12. PCS7串级PID如何连线控制汽包水位三冲量
  13. python股票接口_python获取股票数据接口
  14. 惠普局域网共享打印机设置_打印机共享怎么设置 惠普打印机共享设置步骤介绍【详解】...
  15. 三维扫描3D打印在创客教育中的实际应用
  16. centos系统加入windows域
  17. 【翻译】 Unity3D VR 教程:4.VR中的用户界面
  18. c++ map查找key
  19. 罗永浩“吓尿”大会上,我裤子真湿了
  20. 2022-2028年中国燃气轮机行业市场专项调研及投资前景研究报告

热门文章

  1. 安卓手机如何解除root?解除root教程
  2. MFC中按钮对于键盘回车和空格响应,引发的问题
  3. 经典光流计算方法(HS光流法、Lucas-Kanada方法、Pyramidal LK方法)
  4. 互联网泡沫爆发 | 历史上的今天
  5. NYOJ--万圣节派对
  6. [BZOJ4827][Hnoi2017]礼物(FFT)
  7. crossover的使用过程中出现的问题和解决方法
  8. CDA数据分析师 - SQL数据库基础 查询连接
  9. 零佣金面世 互联网金融改写券商经纪版图
  10. Win10专业版永久激活方法