资讯专栏INFORMATION COLUMN

基于LinkedBlockingQueue实现股票交易系统

30e8336b8229 / 3424人阅读

摘要:与基于数组的队列相同,重载的构造函数可以接受集合指定的初始值。这种队列比基于数组阻塞队列具有更高的吞吐量。创建个交易者实例,将自己出售的订单放入队列中,每个出售订单都将会有随机的交易量。要使用基于优先级的队列,需要提供适当的比较器。

阻塞队列

在阻塞队列的帮助下,许多同步问题都可以被公式化。阻塞队列是队列,当线程试图对空队列进行出列操作,或试图向满的队列中插入条目时,队列就会阻塞。直到其他线程向队列中放入数据时才可以移除,同样,直到其他线程从队列中移除条目之后才可以加入。通过使用 轮询或等待-通知机制可以实现阻塞队列。就轮询机制来说,读线程周期性的调用队列的get方法,直到队列的消息变为可用。至于等待-通知机制,读线程仅仅是等待队列对象,队列对象会在有条目时通知线程。

阻塞队列的特征

阻塞队列的典型特征可以概括如下:

阻塞队列提供了方法来向其中添加条目。这些方法的调用都是阻塞调用的,其中条目的插入必须等待,直到队列的空间变为可用。

队列提供了方法来从中删除条目,对这些方法的调用同样是阻塞调用的。调用者会等待条目被放入空队列

add和remove方法可以选择性地为它们的等待操作提供超时并可能被中断

put和take操作在多带带的线程中实现,从而在两种类型的操作之间提供了良好的绝缘性

不能像阻塞队列中插入null元素

阻塞队列可能受容量的限制

阻塞队列的实现是线程安全的,然而批量操作,比如addAll,没有必要一定原子地执行,

阻塞队列在本质上不支持“关闭”或“停止”操作,这表示没有更多的条目可添加

LinkedBlockingQueue

LinkedBlockingQueue是通过将阻塞队列的最大容量变为可变,进而扩展了数据阻塞队列的概念。你仍然可以在指定容量已禁止过度扩容。如果不指定容量,默认值是最大的整数值。没有容量限制是由好处的,因为如果先飞着晚于预订时间选取条目,生产者无需等待。与基于数组的队列相同,重载的构造函数可以接受集合指定的初始值。这种队列比基于数组阻塞队列具有更高的吞吐量。但同时也有较少的可预见性。除了移除操作在线性时间运行之外,队列的大多数操作都是在常数时间内运行的。

PriorityBlockingQueue

PriorityBlockingQueue是无界队列,可以决定元素的优先顺序,优先级可以由元素的自然顺序或你提供的比较器来确定。依照优先级队列的顺序,视图插入不可比较的对象会导致ClassCastException异常。如果系统资源耗尽,虽然是无界队列,添加操作也会失败,

股票交易系统

</>复制代码

  1. package com.guo.chap18;
  2. import java.io.IOException;
  3. import java.util.concurrent.BlockingQueue;
  4. import java.util.concurrent.LinkedBlockingQueue;
  5. /**
  6. * Created by guo on 17/2/2018.
  7. * 基于阻塞队列的股票交易服务器
  8. * 需求:
  9. * 1、允许交易者往队列中添加出售订单,也可以获取待办的订单
  10. * 2、在任何给定的时间,如果队列已满,交易者就不得不等待某个位置变为空
  11. * 3、购买者必须等待,直到队列中有出售订单可用。
  12. * 4、为了简化情形,假设买方总是必须购买全额数量的可供出售的股票,不可以部分购买。
  13. */
  14. public class StockExchange {
  15. public static void main(String[] args) {
  16. System.out.printf("Hit Enter to terminate %n%n");
  17. //1、创建LinkedBlockingQueue实例,因为是无限容量,所以交易者可以把任何数量的订单放入队列中,
  18. // 如果使用ArrayBlockingQueue,那么将会限制每只股票拥有有限次数的交易。
  19. BlockingQueue orderQueue = new LinkedBlockingQueue<>();
  20. //2、创建Seller卖家实例,Seller是Runnable的实现类。
  21. Seller seller = new Seller(orderQueue);
  22. //3、创建100个交易者实例,将自己出售的订单放入队列中,每个出售订单都将会有随机的交易量。
  23. Thread[] sellerThread = new Thread[100];
  24. for (int i = 0; i < 100; i++) {
  25. sellerThread[i] = new Thread(seller);
  26. sellerThread[i].start();
  27. }
  28. //4、创建100个买家实例,选取待售的订单
  29. Buyer buyer = new Buyer(orderQueue);
  30. Thread[] buyserThread = new Thread[100];
  31. for (int i = 0; i < 100; i++) {
  32. buyserThread[i] = new Thread(buyer);
  33. buyserThread[i].start();
  34. }
  35. try {
  36. //5、一旦创建生产者和消费者线程,他们会永远保持运行,将订单放入队列以及从队列中获取订单
  37. // 根据给定时间的负载情况,定期自我阻塞,终止应用程序的方法是用户在键盘上按下Enter键。
  38. while (System.in.read() != "
  39. ");
  40. } catch (IOException e) {
  41. e.printStackTrace();
  42. }
  43. //6、main函数会中断所有正在运行的生产者和消费者线程,要求它们中指并退出
  44. System.out.println("Terminating");
  45. for (Thread t : sellerThread) {
  46. t.interrupt();
  47. }
  48. for (Thread t : buyserThread) {
  49. t.interrupt();
  50. }
  51. }
  52. }
卖家和买家

</>复制代码

  1. /**
  2. * 卖家
  3. * Seller类实现了Runnable接口并提供了以OrderQueue作为参数的构造函数
  4. */
  5. class Seller implements Runnable {
  6. private BlockingQueue orderQueue;
  7. private boolean shutdownRequest = false;
  8. private static int id;
  9. public Seller(BlockingQueue orderQueue) {
  10. this.orderQueue = orderQueue;
  11. }
  12. @Override
  13. public void run() {
  14. while (shutdownRequest == false) {
  15. //1、在每一次迭代中,为每一次的交易量生产一个随机数
  16. Integer quantity = (int) (Math.random() * 100);
  17. try {
  18. //2、调用put方法,将订单放入队列中,这是阻塞调用,只有在队列容量有限的情况下,
  19. // 线程才需要等待队列中有出现空的位置
  20. orderQueue.put(quantity);
  21. //3、为了方便用户,在控制台打印销售订单的详细信息,以及用于放置销售订单的线程详细信息
  22. System.out.println("Sell order by" + Thread.currentThread().getName() + ": " + quantity);
  23. } catch (InterruptedException e) {
  24. //4、run方法将无限期的运行,定期的向队列中提交订单,通过调用interrupt方法,这个线程可以被另外一个线程中断。
  25. // interrupt方法产生的InterruptException异常简单的将shutdownRequest标志设置为true,将导致run方法无限循环终止
  26. shutdownRequest = true;
  27. }
  28. }
  29. }
  30. }
  31. /**
  32. * 买家
  33. * Buyer类实现了Runnable接口并提供了以OrderQueue作为参数的构造函数
  34. */
  35. class Buyer implements Runnable{
  36. private BlockingQueue orderQueue;
  37. private boolean shutdownRequest = false;
  38. public Buyer(BlockingQueue orderQueue) {
  39. this.orderQueue = orderQueue;
  40. }
  41. @Override
  42. public void run() {
  43. while (shutdownRequest == false) {
  44. try {
  45. //1、run方法通过调用take方法,从队列的头部取出待办的交易,
  46. // 如果队列中没有可用的订单,take方法将阻塞,
  47. Integer quantity = ((Integer) orderQueue.take());
  48. //2、为了方便,打印订单和线程的详细信息
  49. System.out.println("Buy order by " + Thread.currentThread().getName() + ": " + quantity);
  50. } catch (InterruptedException e) {
  51. shutdownRequest = true;
  52. }
  53. }
  54. }
  55. }
输出

</>复制代码

  1. ...
  2. Buy order by Thread-134: 48
  3. Buy order by Thread-134: 83
  4. Buy order by Thread-134: 2
  5. Buy order by Thread-134: 52
  6. Sell order byThread-86: 90
  7. Sell order byThread-86: 19
  8. Sell order byThread-86: 64
  9. Sell order byThread-86: 83
  10. Sell order byThread-86: 27
  11. Buy order by Thread-163: 94
  12. Buy order by Thread-163: 74
  13. ...

当在键盘上按下Enter键使,程序终止

在这个程序中,如果没有使用阻塞队列,访问非同步队列中放置的交易时会发生竞争,每个人都会尝试抢得低于当前市场价格出售的股票,多个交易者会选取统一订单,交易之间会很混乱,由于阻塞队列 确保了同步地访问队列,因此交易的完整性绝不会 受到损害。

在这个例子中使用了LinkedBlockingQueue,气死也可以基于优先级的队列,这样会自动按照交易的买价和卖价对交易进行排列,具有最好买价和最低卖价的订单总是排在队列的头部。要使用基于优先级的队列,需要提供适当的比较器。

说明

1、GitHub代码欢迎star。你们轻轻的一点,对我鼓励特大。

2、个人认为学习语言最好的方式就是模仿思考别人为什么这么写。结合栗子效果更好,也能记住知识点

3、只因为自己知识欠缺,语言组织能力不行,所以只能以这样方式记录。感觉效果很好。

4、本文基于《Java 7 编程高级进阶》所写,写的非常不错,建议大家去看看

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68509.html

相关文章

  • Python量化交易基础讲堂——管理概率==理性交易

    摘要:那么我们改变概率这个因子,将它放大到,我们邀请个人参与局看下效果看来结果还不错,只要增加盈利的概率,就可以在市场中获得收益,这就是量化交易的魅力管理概率理性交易。 在《Python实战-构建基于股票的量化交易系统》小册子中,我们以股票为交易标的讲解量化交易的学习,主要原因是股票的风险和收益介于期货和基金之间。期货一方面加了杠杆,另一方面走势变化非常迅速,稍有不慎有可能血本无归,这不太适...

    AWang 评论0 收藏0
  • 从理想到现实, 你不知道的区块链

    摘要:简而言之,区块链说的是由区块用某种方式组织起来的链条。在本文中,我们说的区块链技术实际上是一种分布式数据库技术。事实上,当使用基于区块链的系统时,人们对中心机构的信任转而被对数学的信任所取代。因而,基于区块链的系统是安全的。 区块链是什么?我们来看一下区块链在维基百科上被大家公认的官方定义: 一个区块链是一个基于比特币协议的不需要许可的分布式数据库,它维护了一个持续增长的不可被篡改和修...

    seasonley 评论0 收藏0
  • 金融套利策略:理解统计套利的工作原理

    摘要:后一种方法被称之为多因子统计套利模型。套利套利可以被称为交叉资产套利的一种形式,它可以识别的价值与其相关资产之间的差异。目前,统计套利策略已经成为了对冲基金和投资银行的主要力量。 作者:chen_h微信号 & QQ:862251340微信公众号:coderpai简书地址:https://www.jianshu.com/p/ea2... 1. 什么是定量交易 定量交易是通过统计技术(或...

    whataa 评论0 收藏0
  • 说说股票配资系统中实盘交易接口的开发

    摘要:做股票配资系统难免会用到交易接口,好用的能用的接口也少。券商那边也不提供,那索性自己开发股票配资实盘交易接口了。 做股票配资系统难免会用到交易接口,好用的能用的接口也少。券商那边也不提供,那索性自己开发股票配资实盘交易接口了。经过多次尝试,总算搞出来了,实时交易接口可以获取用户数据,实时对接,账户信息,委托买入卖出,支持多家券商。 种类4(可撤单)返回 {data1: { 委托类别:...

    leoperfect 评论0 收藏0

发表评论

0条评论

30e8336b8229

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<