要求:用两个线程模拟存票、售票过程。但要求每存入一张票,就售出一张票,售出后,再存入,直到售完为止。

用到的知识点:线程等待、唤醒、可能的线程中断异常

下面的方式一和方式二采用的是唤醒所有等待的线程,即wait()和notify()方法

方式一:继承Thread

class Tickets //定义(资源)票类
{protected int size;//总票数int number=0;      //票号Boolean available=false;//表示当前是否有票可售public Tickets(int size){this.size = size;}public synchronized void store()  //同步方法,实现存票功能
    {if(available)  //如果线程还有票可售,则存票线程等待try{wait();}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+"存入第【"+(++number)+"】张票");available = true;notify(); //存票后,唤醒售票线程开始售票
    }public synchronized void sale()  //同步方法,实现售票功能
    {if(!available)  //如果线程没有票可售,则售票线程等待try{wait();}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+"售出第【"+(number)+"】张票");available = false;notify(); //售票后,唤醒存票线程开始存票
    }
}class Productor extends Thread  //定义生产者(存票)线程类
{private Tickets t;public Productor(Tickets t){this.t = t;}public void run(){while(true){  if(t.number<t.size)t.store();elseSystem.exit(0);} }
}class Costomer extends Thread   //定义消费者(售票)线程类
{private Tickets t;public Costomer(Tickets t){this.t = t;}public void run(){ while(true){  if(t.number<=t.size)t.sale();elseSystem.exit(0);}}
}
class  TicketStoreSale3
{public static void main(String[] args) {Tickets t = new Tickets(10);Productor t1 = new Productor(t);Costomer t2 = new Costomer(t);t1.start();t2.start();}
}

方式二:实现Runnable接口

class Tickets //定义(资源)票类
{protected int size;//总票数int number=0;      //票号Boolean available=false;//表示当前是否有票可售public Tickets(int size){this.size = size;}public synchronized void store()  //同步方法,实现存票功能
    {if(available)  //如果线程还有票可售,则存票线程等待try{wait();}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+"存入第【"+(++number)+"】张票");available = true;notify(); //存票后,唤醒售票线程开始售票
    }public synchronized void sale()  //同步方法,实现售票功能
    {if(!available)  //如果线程没有票可售,则售票线程等待try{wait();}catch(InterruptedException e){}System.out.println(Thread.currentThread().getName()+"售出第【"+(number)+"】张票");available = false;notify(); //售票后,唤醒存票线程开始存票
    }
}class Productor implements Runnable  //实现一个接口,生产者(存票)线程类
{private Tickets t;public Productor(Tickets t){this.t = t;}public void run(){while(true){  if(t.number<t.size)t.store();elseSystem.exit(0);} }
}class Costomer implements Runnable   //实现一个接口,消费者(售票)线程类
{private Tickets t;public Costomer(Tickets t){this.t = t;}public void run(){ while(true){  if(t.number<=t.size)t.sale();elseSystem.exit(0);}}
}
class  TicketStoreSale
{public static void main(String[] args) {Tickets t = new Tickets(10);Thread t1 = new Thread(new Productor(t));Thread t2 = new Thread( new Costomer(t));t1.start();t2.start();}
}

方式三:在JDK1.5中提供了多线程升级解决方案。
将同步Synchronized替换成显式的Lock操作。
将Object中的wait,notify,notifyAll,替换成了Conditon对象。
该对象可以对Lock锁,进行获取。
该示例中,实现了本方只唤醒对方操作。

import java.util.concurrent.locks.*;
class Tickets //定义(资源)票类
{protected int size;//总票数int number=0;      //票号Boolean available=false;//表示当前是否有票可售public Tickets(int size){this.size = size;}Lock lock = new ReentrantLock();  //创建锁Condition notFull = lock.newCondition(); //创建未满状态Condition notEmpty = lock.newCondition();//创建未空状态public void store() throws InterruptedException //同步方法,实现存票功能
    {lock.lock();try{if(available)  //如果线程还有票可售,则存票线程等待
         notEmpty.await();System.out.println(Thread.currentThread().getName()+"存入第【"+(++number)+"】张票");available = true;notFull.signal();//存票后,唤醒售票线程开始售票
      } finally{lock.unlock();   //释放锁资源
        }}public void sale() throws InterruptedException  //同步方法,实现售票功能
    {lock.lock();try{if(!available)  //如果线程没有票可售,则售票线程等待
        notFull.await();System.out.println(Thread.currentThread().getName()+"售出第【"+(number)+"】张票");available = false;notEmpty.signal(); //售票后,唤醒存票线程开始存票
      }finally{lock.unlock();  //释放锁资源
        }}
}class Productor implements Runnable  //实现一个接口,生产者(存票)线程类
{private Tickets t;public Productor(Tickets t){this.t = t;}public void run(){while(true){  if(t.number<t.size)try{t.store();}catch (InterruptedException e){e.printStackTrace();}elseSystem.exit(0);} }
}class Costomer implements Runnable   //实现一个接口,消费者(售票)线程类
{private Tickets t;public Costomer(Tickets t){this.t = t;}public void run(){ while(true){  if(t.number<=t.size)try{t.sale();}catch (InterruptedException e){e.printStackTrace();}elseSystem.exit(0);}}
}
class  TicketStoreSaleLock
{public static void main(String[] args) {Tickets t = new Tickets(10);Thread t1 = new Thread(new Productor(t));Thread t2 = new Thread( new Costomer(t));t1.start();t2.start();}
}

转载于:https://www.cnblogs.com/XYQ-208910/p/4915691.html

Java:多线程之生产者与消费者相关推荐

  1. Java多线程技术~生产者和消费者问题

    Java多线程技术~生产者和消费者问题 本文是上一篇文章的后续,详情点击该连接 线程通信 应用场景:生产者和消费者问题 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取 ...

  2. Java多线程案例--生产者和消费者模型(送奶人和喝奶人的故事!)

    文章目录 一.进程和线程 1.进程 2.线程 3.进程与线程的区别 二.生产者和消费者模型 1.生产者消费者模式概述 2.奶箱类 3.生产者类 4.消费者类 三.测试 1.测试类(BoxDemo) 2 ...

  3. java多线程之——生产者和消费者(详解及提高)

    目录 前情引入 简单介绍 预备知识 代码及详解 简单代码 基本解释 生产者线程类 消费者线程类 测试类 执行流程 控制台输出 自我提高 问题一 问题二 升级代码 总结 前情引入 做一些简单的认识和告知 ...

  4. java多线程之生产者和消费者问题

    线程通信:不同的线程执行不同的任务,如果这些任务有某种关系,线程之间必须能够通信,协调完成工作. 经典的生产者和消费者案例(Producer/Consumer): 分析案例: 1):生产者和消费者应该 ...

  5. Java并发编程系列18:多线程之生产者和消费者模式_信号灯法(wait/notify通知机制)

    1.生产者消费者模式 生产者消费者问题(Producer-consumer problem),也称为有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例.该问题 ...

  6. java线程之生产者与消费者

    预习java线程的三种创建方式 package com.bj.thread;import java.util.concurrent.*;/*** @FileName: TestThread* @Rem ...

  7. java多线程 生产者消费者_java多线程之-生产者与消费者

    java多线程之-并发协作[生产者与消费者]模型 对于多线程程序来说,不管c/c++ java python 等任何编程语言,生产者与消费者模型都是最为经典的.也就是可以说多线程的并发协作 对于此模型 ...

  8. java多线程之生产者消费者问题

    今天研究了一下Java多线程,根据老师上课讲的和写的,自己写了一下多线程中的经典问题-----生产者消费者经典问题, package producerconsumer; public class Pr ...

  9. Java多线程编程——生产者消费者问题

    一.问题介绍 生产者消费者问题是一个经典的多线程同步问题.该问题描述了两个进程--即所谓的"生产者"和"消费者"--在实际运行时会发生的问题.生产者的主要作用是 ...

  10. Java多线程:生产者消费者模型

    文章目录 1.生产者消费者 1.1 生产者和消费者模式概述 1.2 经典案例:生产者和消费者 1.2.1 Object类的等待和唤醒方法 1.2.2 代码实现 1.3 生产者和消费者案例优化 1.3. ...

最新文章

  1. Lodash学习--Array篇
  2. MySql 数据库 - 重置数据库、重置初始密码方法,数据库初始化方法,长时间不用忘记密码暴力解决方法
  3. Linux基本信号的使用
  4. 大会门票限免最后一周!来聊聊 NVIDIA、抖音等大厂的 AI 技术落地
  5. linux 每日学一点《Linux链接文件类型》
  6. 通过系统架构设计师考试的一点经验(2019年软考)+学习资料下载
  7. 发几个iphone助手相关代码,供大家参考
  8. python生成和校验uuid
  9. 线性代数、微积分学习与回顾
  10. 2#使用新安装的ubuntu,之vim必须知道的细节
  11. STAR法则的理解及事例
  12. pytorch例子学习——NEURAL TRANSFER USING PYTORCH神经迁移
  13. nodejs使用node-ffi-napi 访问dll文件
  14. 微信小程序(五)新版的用户授权和判断是否是否已经授权和自动提示更新版本
  15. LR 杂记--nmon 分析 AIX 和 Linux 性能
  16. 智慧公厕解决方案,光明源智慧公厕解决方案全解
  17. Android近距离通信
  18. 数学建模中的插值问题
  19. Python-数据的多种存储形式
  20. 数据可视化系列-06数据分析工具QuickBI

热门文章

  1. 如何在苹果Mac上删除APFS卷?
  2. 如何在Mac上使用听写进行语音到文本的键入
  3. Mac系统如何删除.DS_Store文件且不再生
  4. H5 手势滑动以及滚动相关资料
  5. C程序设计语言(2)文摘
  6. Java中interface接口与abstract class抽象类的区别
  7. grub 与grub2
  8. PowerPivot 和 SQL Azure 快速入门
  9. Linux下新手基本操作及技巧看图上路
  10. Android 应用程序获得系统权限