摘要:与基于数组的队列相同,重载的构造函数可以接受集合指定的初始值。这种队列比基于数组阻塞队列具有更高的吞吐量。创建个交易者实例,将自己出售的订单放入队列中,每个出售订单都将会有随机的交易量。要使用基于优先级的队列,需要提供适当的比较器。
阻塞队列
在阻塞队列的帮助下,许多同步问题都可以被公式化。阻塞队列是队列,当线程试图对空队列进行出列操作,或试图向满的队列中插入条目时,队列就会阻塞。直到其他线程向队列中放入数据时才可以移除,同样,直到其他线程从队列中移除条目之后才可以加入。通过使用 轮询或等待-通知机制可以实现阻塞队列。就轮询机制来说,读线程周期性的调用队列的get方法,直到队列的消息变为可用。至于等待-通知机制,读线程仅仅是等待队列对象,队列对象会在有条目时通知线程。
阻塞队列的特征阻塞队列的典型特征可以概括如下:
阻塞队列提供了方法来向其中添加条目。这些方法的调用都是阻塞调用的,其中条目的插入必须等待,直到队列的空间变为可用。
队列提供了方法来从中删除条目,对这些方法的调用同样是阻塞调用的。调用者会等待条目被放入空队列
add和remove方法可以选择性地为它们的等待操作提供超时并可能被中断
put和take操作在多带带的线程中实现,从而在两种类型的操作之间提供了良好的绝缘性
不能像阻塞队列中插入null元素
阻塞队列可能受容量的限制
阻塞队列的实现是线程安全的,然而批量操作,比如addAll,没有必要一定原子地执行,
阻塞队列在本质上不支持“关闭”或“停止”操作,这表示没有更多的条目可添加
LinkedBlockingQueueLinkedBlockingQueue是通过将阻塞队列的最大容量变为可变,进而扩展了数据阻塞队列的概念。你仍然可以在指定容量已禁止过度扩容。如果不指定容量,默认值是最大的整数值。没有容量限制是由好处的,因为如果先飞着晚于预订时间选取条目,生产者无需等待。与基于数组的队列相同,重载的构造函数可以接受集合指定的初始值。这种队列比基于数组阻塞队列具有更高的吞吐量。但同时也有较少的可预见性。除了移除操作在线性时间运行之外,队列的大多数操作都是在常数时间内运行的。
PriorityBlockingQueuePriorityBlockingQueue是无界队列,可以决定元素的优先顺序,优先级可以由元素的自然顺序或你提供的比较器来确定。依照优先级队列的顺序,视图插入不可比较的对象会导致ClassCastException异常。如果系统资源耗尽,虽然是无界队列,添加操作也会失败,
股票交易系统package com.guo.chap18; import java.io.IOException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; /** * Created by guo on 17/2/2018. * 基于阻塞队列的股票交易服务器 * 需求: * 1、允许交易者往队列中添加出售订单,也可以获取待办的订单 * 2、在任何给定的时间,如果队列已满,交易者就不得不等待某个位置变为空 * 3、购买者必须等待,直到队列中有出售订单可用。 * 4、为了简化情形,假设买方总是必须购买全额数量的可供出售的股票,不可以部分购买。 */ public class StockExchange { public static void main(String[] args) { System.out.printf("Hit Enter to terminate %n%n"); //1、创建LinkedBlockingQueue实例,因为是无限容量,所以交易者可以把任何数量的订单放入队列中, // 如果使用ArrayBlockingQueue,那么将会限制每只股票拥有有限次数的交易。 BlockingQueue卖家和买家orderQueue = new LinkedBlockingQueue<>(); //2、创建Seller卖家实例,Seller是Runnable的实现类。 Seller seller = new Seller(orderQueue); //3、创建100个交易者实例,将自己出售的订单放入队列中,每个出售订单都将会有随机的交易量。 Thread[] sellerThread = new Thread[100]; for (int i = 0; i < 100; i++) { sellerThread[i] = new Thread(seller); sellerThread[i].start(); } //4、创建100个买家实例,选取待售的订单 Buyer buyer = new Buyer(orderQueue); Thread[] buyserThread = new Thread[100]; for (int i = 0; i < 100; i++) { buyserThread[i] = new Thread(buyer); buyserThread[i].start(); } try { //5、一旦创建生产者和消费者线程,他们会永远保持运行,将订单放入队列以及从队列中获取订单 // 根据给定时间的负载情况,定期自我阻塞,终止应用程序的方法是用户在键盘上按下Enter键。 while (System.in.read() != " "); } catch (IOException e) { e.printStackTrace(); } //6、main函数会中断所有正在运行的生产者和消费者线程,要求它们中指并退出 System.out.println("Terminating"); for (Thread t : sellerThread) { t.interrupt(); } for (Thread t : buyserThread) { t.interrupt(); } } }
/** * 卖家 * Seller类实现了Runnable接口并提供了以OrderQueue作为参数的构造函数 */ class Seller implements Runnable { private BlockingQueue orderQueue; private boolean shutdownRequest = false; private static int id; public Seller(BlockingQueue orderQueue) { this.orderQueue = orderQueue; } @Override public void run() { while (shutdownRequest == false) { //1、在每一次迭代中,为每一次的交易量生产一个随机数 Integer quantity = (int) (Math.random() * 100); try { //2、调用put方法,将订单放入队列中,这是阻塞调用,只有在队列容量有限的情况下, // 线程才需要等待队列中有出现空的位置 orderQueue.put(quantity); //3、为了方便用户,在控制台打印销售订单的详细信息,以及用于放置销售订单的线程详细信息 System.out.println("Sell order by" + Thread.currentThread().getName() + ": " + quantity); } catch (InterruptedException e) { //4、run方法将无限期的运行,定期的向队列中提交订单,通过调用interrupt方法,这个线程可以被另外一个线程中断。 // interrupt方法产生的InterruptException异常简单的将shutdownRequest标志设置为true,将导致run方法无限循环终止 shutdownRequest = true; } } } } /** * 买家 * Buyer类实现了Runnable接口并提供了以OrderQueue作为参数的构造函数 */ class Buyer implements Runnable{ private BlockingQueue orderQueue; private boolean shutdownRequest = false; public Buyer(BlockingQueue orderQueue) { this.orderQueue = orderQueue; } @Override public void run() { while (shutdownRequest == false) { try { //1、run方法通过调用take方法,从队列的头部取出待办的交易, // 如果队列中没有可用的订单,take方法将阻塞, Integer quantity = ((Integer) orderQueue.take()); //2、为了方便,打印订单和线程的详细信息 System.out.println("Buy order by " + Thread.currentThread().getName() + ": " + quantity); } catch (InterruptedException e) { shutdownRequest = true; } } } }输出
... Buy order by Thread-134: 48 Buy order by Thread-134: 83 Buy order by Thread-134: 2 Buy order by Thread-134: 52 Sell order byThread-86: 90 Sell order byThread-86: 19 Sell order byThread-86: 64 Sell order byThread-86: 83 Sell order byThread-86: 27 Buy order by Thread-163: 94 Buy order by Thread-163: 74 ...
当在键盘上按下Enter键使,程序终止
在这个程序中,如果没有使用阻塞队列,访问非同步队列中放置的交易时会发生竞争,每个人都会尝试抢得低于当前市场价格出售的股票,多个交易者会选取统一订单,交易之间会很混乱,由于阻塞队列 确保了同步地访问队列,因此交易的完整性绝不会 受到损害。
在这个例子中使用了LinkedBlockingQueue,气死也可以基于优先级的队列,这样会自动按照交易的买价和卖价对交易进行排列,具有最好买价和最低卖价的订单总是排在队列的头部。要使用基于优先级的队列,需要提供适当的比较器。
说明1、GitHub代码欢迎star。你们轻轻的一点,对我鼓励特大。
2、个人认为学习语言最好的方式就是模仿、思考别人为什么这么写。结合栗子效果更好,也能记住知识点。
3、只因为自己知识欠缺,语言组织能力不行,所以只能以这样方式记录。感觉效果很好。
4、本文基于《Java 7 编程高级进阶》所写,写的非常不错,建议大家去看看
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/68509.html
摘要:那么我们改变概率这个因子,将它放大到,我们邀请个人参与局看下效果看来结果还不错,只要增加盈利的概率,就可以在市场中获得收益,这就是量化交易的魅力管理概率理性交易。 在《Python实战-构建基于股票的量化交易系统》小册子中,我们以股票为交易标的讲解量化交易的学习,主要原因是股票的风险和收益介于期货和基金之间。期货一方面加了杠杆,另一方面走势变化非常迅速,稍有不慎有可能血本无归,这不太适...
摘要:简而言之,区块链说的是由区块用某种方式组织起来的链条。在本文中,我们说的区块链技术实际上是一种分布式数据库技术。事实上,当使用基于区块链的系统时,人们对中心机构的信任转而被对数学的信任所取代。因而,基于区块链的系统是安全的。 区块链是什么?我们来看一下区块链在维基百科上被大家公认的官方定义: 一个区块链是一个基于比特币协议的不需要许可的分布式数据库,它维护了一个持续增长的不可被篡改和修...
摘要:后一种方法被称之为多因子统计套利模型。套利套利可以被称为交叉资产套利的一种形式,它可以识别的价值与其相关资产之间的差异。目前,统计套利策略已经成为了对冲基金和投资银行的主要力量。 作者:chen_h微信号 & QQ:862251340微信公众号:coderpai简书地址:https://www.jianshu.com/p/ea2... 1. 什么是定量交易 定量交易是通过统计技术(或...
摘要:做股票配资系统难免会用到交易接口,好用的能用的接口也少。券商那边也不提供,那索性自己开发股票配资实盘交易接口了。 做股票配资系统难免会用到交易接口,好用的能用的接口也少。券商那边也不提供,那索性自己开发股票配资实盘交易接口了。经过多次尝试,总算搞出来了,实时交易接口可以获取用户数据,实时对接,账户信息,委托买入卖出,支持多家券商。 种类4(可撤单)返回 {data1: { 委托类别:...
阅读 2904·2023-04-25 21:23
阅读 2996·2021-09-22 15:24
阅读 837·2019-08-30 12:55
阅读 2078·2019-08-29 18:42
阅读 2570·2019-08-29 16:27
阅读 886·2019-08-26 17:40
阅读 2154·2019-08-26 13:29
阅读 2584·2019-08-26 11:45