Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.概述

在本文中,我们将在看DELAYQUE.从建构中的构造java.util.concurrent.包裹。这是一个可在生产者 - 消费者程序中使用的阻塞队列。

它有一个非常有用的特征 -当消费者想要从队列中占用一个元素时,它们只有在该特定元素的延迟过期时才会采用它。

2.实施延迟用于元素DELAYQUE.

我们想要投入的每个元素DELAYQUE.需要实施延迟界面。让我们说我们想要创建一个DelayObject.班级。那个班级的实例将被投入Delayqueue。

我们会通过它细绳数据和delayinmilliseconds.与其构造函数的参数:

公共类DelayObject实现延迟{私有字符串数据;私人长期开始;公共DelazeObject(字符串数据,长时间inmilliseconds){this.data = data;this.starttime = system.currenttimemillis()+ delayinmilliseconds;}

我们正在定义一个开始时间 -这是应从队列中消耗元素的时间。接下来,我们需要实施getdelay()方法 - 它应该在给定时间单位中返回与此对象相关联的剩余延迟。

因此,我们需要使用timeUnit.Convert()返回适当剩余延迟的方法时髦:

@override公共长getdelay(时间单位){long diff = starttime  -  system.currenttimemillis();返回Unit.convert(Diff,TimeUnit.milliseconds);}

当消费者试图从队列中占据一个元素时,DELAYQUE.将执行getdelay()找出允许从队列返回该元素。如果是getdelay()方法将返回零或负数,这意味着可以从队列中检索它。

我们还需要实施相比于()方法,因为所在的元素DELAYQUE.将根据到期时间进行排序。将首先过期的项目保存在队列的头部,并且在队列的尾部保持最有效期的元素:

@override public int compareto(延迟o){return ints.saturatedcast(this.starttime  - ((delayobject)o).starttime);}

3.Delayqueue C.Onsumer和生产者

能够测试我们的DELAYQUE.我们需要实施生产者和消费者逻辑。Producer类获取队列,要生成的元素数,以及以毫秒为参数的每个消息的延迟。

然后当何时跑步()调用方法,将元素放入队列中,然后在每个Put中睡眠500毫秒:

公共类LayerQueueProducer实现Runnable {private blockingqueue 队列;私人整数NumberofeLementStroduce;私有整数delayOfeachProduceMessageMilliseconds;//标准构造函数@override public void run(for(int i = 0; i 

消费者的实现非常相似,但它还跟踪所消耗的消息数量:

公共类LayerQueueConsumer实现Runnable {Private BlockingQueue 队列;私人整数NumberofElementStotake;公共atomicinteger numberofconsumedelements = new oromicinteger();//标准构造函数@override public void run(for(int i = 0; i 

4.DELAYQUE.使用测试

测试行为Delayqueue,我们将创建一个生产者线程和一个消费者线程。

生产者遗嘱放()两个对象到队列上,延迟为500毫秒。测试断言消费者消耗了两条消息:

@test public vivendelayqueue_whenproduceElement _thenshouldconsumautemtergivendelay()抛出中断{//给定Exectorservice executor = executors.newfixedThreadPool(2);blockingqueue 队列= new delayqueue <>();int numberofelementstoproduce = 2;int delayofeachproducemessagemilliseconds = 500;delayqueueconsumer消费者=新的delayqueueConsumer(队列,numberofelementstoproduce);delayqueueproducer制片商=新的delayqueueproducer(队列,numperofelementstoproduce,delayofeachproducemessagemilliseconds);// executor.submit(制作人);executor.submit(消费者);//然后executor.aittermination(5,tateneUnit.seconds);executor.shutdown(); assertEquals(consumer.numberOfConsumedElements.get(), numberOfElementsToProduce); }

我们可以观察运行此程序将产生以下输出:

put对象:{data ='86046157-e8a0-49b2-9cbb-8326124bcab8',starttime = 1494069868007}消费者采取:{data ='86046157-e8a0-49b2-9cbb-8326124bcab8',starttime = 1494069868007} pure对象:{data ='D47927EF-18C7-449B-B491-5FF30E6795ED',STARTTIME = 1494069868512}消费者采取:{DATA ='D479270-18C7-449B-B491-5FF30E6795ED',STARTTIME = 1494069868512}

制作人将对象放置,之后是消耗延迟到期的第一个对象。

第二个元素发生了相同的情况。

5.消费者无法在给定的时间消耗

让我们说我们有一个生产的制片人,正在制作一个要素到期10秒

int numberofelementstoproduce = 1;int delayofeachproducemessagemilliseconds = 10_000;delayqueueconsumer消费者=新的delayqueueConsumer(队列,numberofelementstoproduce);delayqueueproducer制片商=新的delayqueueproducer(队列,numperofelementstoproduce,delayofeachproducemessagemilliseconds);

我们将开始测试,但它将在5秒后终止。由于特征Delayqueue,消费者将无法使用队列中的消息,因为该元素尚未过期:

executor.submit(生产者);executor.submit(消费者);executer.awaittermination(5,TimeUnit.seconds);executor.shutdown();assertequals(confecer.numberofconsumedElements.get(),0);

注意,消费者的numberofconsumedelements.值等于零。

6.产生具有直接到期的元素

当实现的实施延迟信息getdelay()方法返回一个负数,这意味着给定元素已经过期。在这种情况下,生产者将立即消耗该元素。

我们可以测试带负延迟产生元素的情况:

int numberofelementstoproduce = 1;int delayofeachproducemessagemilliseconds = -10_000;delayqueueconsumer消费者=新的delayqueueConsumer(队列,numberofelementstoproduce);delayqueueproducer制片商=新的delayqueueproducer(队列,numperofelementstoproduce,delayofeachproducemessagemilliseconds);

当我们启动测试用例时,消费者将立即消耗该元素,因为它已过期:

executor.submit(生产者);executor.submit(消费者);executor.aittermination(1,TimeUnit.Seconds);executor.shutdown();assertequals(confimer.numberofconsumedElements.get(),1);

7.结论

在这篇文章中,我们正在看DELAYQUE.从建构中的构造java.util.concurrent.包裹。

我们实施了A.延迟从队列中生成和消耗的元素。

我们利用我们的实施DELAYQUE.消耗已过期的元素。

所有这些示例和代码片段的实现可以在其中找到GitHub项目- 这是一个Maven项目,因此应该易于导入和运行。

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
评论在本文上关闭!