- 浏览: 611397 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
月光杯:
问题解决了吗?
Exceptions in HDFS -
iostreamin:
神,好厉害,这是我找到的唯一可以ac的Java代码,厉害。
[leetcode] word ladder II -
standalone:
One answer I agree with:引用Whene ...
How many string objects are created? -
DiaoCow:
不错!,一开始对这些确实容易犯迷糊
erlang中的冒号 分号 和 句号 -
standalone:
Exception in thread "main& ...
one java interview question
今天不忙,学习一下java.util.concurrent.DelayQueue这个类的使用。参照了
http://www.concretepage.com/java/example_delayqueue_java.php
上的例子,但是这里有个坑。
先看一下整个code吧:
注意getDelay(TimeUnit unit),这个是实现Delayed这个接口时候必须要实现的一个方法,容易遇坑的地方就是
这里应该使用的TimeUnit.MILLISECONDS而不是TimeUnit.NANOSECONDS,但是你会发现不管你用哪一个(或者其他的TimeUnit),这个程序的正确性是ok的,都会delay你所要的时间,例如分别使用这两种TimeUnit的输出:
If using MILLISECONDS:
current time in ms: 1369644922697
current time in ms: 1369644923697, element:e1
current time in ms: 1369644924197, element:e3
current time in ms: 1369644927697, element:e2
If using NANOSECONDS:
current time in ms: 1369645748910
current time in ms: 1369645749910, element:e1
current time in ms: 1369645750410, element:e3
current time in ms: 1369645753910, element:e2
那么会有什么问题呢?
看一下DelayQueue的take()方法会发现,在队列首对象的delay>0的时候,等待的时间单位是nanos(193行),所以如果我刚才getDelay()里面没有将ms转换成ns,那么数值会小很多,line 193 会很快执行,再次循环进行判断,delay仍然大于0,注意,总的等待时间是固定的,现在是每次wait的时间片变小了,所以循环的次数多了,造成一个结果就是cpu占用上升!
如果打印出每次delay的值便可以看到用nanos多做了多少次循环,读者可以自己看一下,呵呵。
遇到这个坑的人我google到有:
http://www.blogjava.net/killme2008/archive/2010/10/22/335897.html
http://www.concretepage.com/java/example_delayqueue_java.php
上的例子,但是这里有个坑。
先看一下整个code吧:
import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class DelayQueueExample { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub DelayQueue<DelayedElement> dq=new DelayQueue<DelayedElement>(); long now = System.currentTimeMillis(); System.out.println("current time in ms: " + now); DelayedElement ob1=new DelayedElement("e1", now + 1000); DelayedElement ob2=new DelayedElement("e2", now + 5000); DelayedElement ob3=new DelayedElement("e3", now + 1500); dq.add(ob1); dq.add(ob2); dq.add(ob3); try { Thread.sleep(1); } catch (InterruptedException e) { throw new RuntimeException( e ); } while(dq.size() > 0){ try { DelayedElement e = dq.take(); System.out.println("current time in ms: " + System.currentTimeMillis() + ", element:" + e.name); } catch (InterruptedException e) { throw new RuntimeException( e ); } } } static class DelayedElement implements Delayed { public long time; public String name; public DelayedElement(String name, long time){ this.name = name; this.time = time; } @Override public int compareTo(Delayed o) { // TODO Auto-generated method stub if(this.time < ((DelayedElement)o).time) return -1; else if(this.time > ((DelayedElement)o).time)return 1; else return 0; } @Override public long getDelay(TimeUnit unit) { // TODO Auto-generated method stub long r = unit.convert(time - System.currentTimeMillis(), TimeUnit.NANOSECONDS); //System.out.println("delay:" + r); return r; } } }
注意getDelay(TimeUnit unit),这个是实现Delayed这个接口时候必须要实现的一个方法,容易遇坑的地方就是
long r = unit.convert(time - System.currentTimeMillis(), TimeUnit.NANOSECONDS);
这里应该使用的TimeUnit.MILLISECONDS而不是TimeUnit.NANOSECONDS,但是你会发现不管你用哪一个(或者其他的TimeUnit),这个程序的正确性是ok的,都会delay你所要的时间,例如分别使用这两种TimeUnit的输出:
If using MILLISECONDS:
current time in ms: 1369644922697
current time in ms: 1369644923697, element:e1
current time in ms: 1369644924197, element:e3
current time in ms: 1369644927697, element:e2
If using NANOSECONDS:
current time in ms: 1369645748910
current time in ms: 1369645749910, element:e1
current time in ms: 1369645750410, element:e3
current time in ms: 1369645753910, element:e2
那么会有什么问题呢?
Retrieves and removes the head of this queue, waiting if necessary until an element with an expired delay is available on this queue. Returns: the head of this queue Throws: java.lang.InterruptedException 181 182 public E take() throws InterruptedException { 183 final ReentrantLock lock = this.lock; 184 lock.lockInterruptibly(); 185 try { 186 for (;;) { 187 E first = q.peek(); 188 if (first == null) { 189 available.await(); 190 } else { 191 long delay = first.getDelay(TimeUnit.NANOSECONDS); 192 if (delay > 0) { 193 long tl = available.awaitNanos(delay); 194 } else { 195 E x = q.poll(); 196 assert x != null; 197 if (q.size() != 0) 198 available.signalAll(); // wake up other takers 199 return x; 200 201 } 202 } 203 } 204 } finally { 205 lock.unlock(); 206 } 207 }
看一下DelayQueue的take()方法会发现,在队列首对象的delay>0的时候,等待的时间单位是nanos(193行),所以如果我刚才getDelay()里面没有将ms转换成ns,那么数值会小很多,line 193 会很快执行,再次循环进行判断,delay仍然大于0,注意,总的等待时间是固定的,现在是每次wait的时间片变小了,所以循环的次数多了,造成一个结果就是cpu占用上升!
如果打印出每次delay的值便可以看到用nanos多做了多少次循环,读者可以自己看一下,呵呵。
遇到这个坑的人我google到有:
http://www.blogjava.net/killme2008/archive/2010/10/22/335897.html
发表评论
-
ssl 与 java 实例
2014-01-27 10:10 844http://www.iteye.com/topic/1125 ... -
Java NIO
2014-01-10 21:28 744看了这个java nio的教程,明白了什么是Selector. ... -
再谈Java的wait(), sleep(), notify()和notifyAll()
2013-07-25 10:59 1943一段时间不用java,这些概念就全混淆了,有必要彻底澄清一下, ... -
Why singleton is anti-pattern?
2013-07-03 10:12 912OO Test Other reasons? -
How to generate the serialVersionUID when you implement Serializable interface,j
2013-07-01 10:52 987http://docs.oracle.com/javase/6 ... -
Java Override的两个问题
2013-06-01 11:40 9871: 如果子类中的方法的参数是父类的方法的子类型,那么算不算o ... -
Java常用类API统计
2013-06-01 11:35 0String charAt(int) compareTo( ... -
How many string objects are created?
2013-06-01 10:18 1356This is a very common java inte ... -
[leetcode] Balanced Binary Tree
2013-04-28 14:08 1615Check if a binary tree is balan ... -
[leetcode] find median of two sorted arrays
2013-04-26 10:55 1501http://leetcode.com/onlinejudge ... -
[leetcode] word ladder
2013-04-25 15:05 2309Q: Given two words (start and ... -
[leetcode] word ladder II
2013-04-15 07:35 12088http://leetcode.com/onlinejudge ... -
[leetcode] Count and Say
2013-04-12 14:05 2280http://leetcode.com/onlinejudge ... -
Date/Time处理函数总结 [To Do]
2013-04-12 10:46 708几种我所用到的用来处理日期,时间的函数总结。 Perl 1 ... -
[leetcode] Palindrome Partition
2013-04-12 10:25 1345http://leetcode.com/onlinejudge ... -
[leetcode] Palindrome Partitioning II
2013-04-11 16:45 1550http://leetcode.com/onlinejudge ... -
Profiling your Java code using Spring
2013-03-05 15:02 730Quite good article!!! http://w ... -
Java的Generics的几点限制
2012-12-28 15:00 4796参见 http://docs.oracle.com/ ... -
Overriding Method Using Parameter That is a Subclass?
2012-12-27 22:14 929参见 http://www.coderanch.com/t/3 ... -
Java的Generics和c++的Template到底有什么不同?
2012-12-27 16:21 3303先了解Java的Generics: 根据Java的文档,Jav ...
相关推荐
在Java编程中,DelayQueue是一种特殊的并发队列,它遵循先进先出(FIFO)原则,但具有一个独特的特性:元素只有在其指定的延迟时间过去之后才能被获取和处理。这个特性使得DelayQueue成为实现定时任务和延迟操作的...
DelayQueue是Java多线程并发开发中的一种常用的数据结构,它是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象。DelayQueue的主要作用是按照对象的延迟时间来排序,以便在合适的时刻从队列中取出对象。 ...
`DelayQueue`是Java并发库`java.util.concurrent`中的一个数据结构,它是一个基于优先级队列的无界阻塞队列,可以用于存储具有延迟时间的元素。而Redis则是一个高性能的键值数据库,通过其丰富的数据结构和操作,...
DelayQueue的使用以及注意事项,这里需要由BlockingQueue的基本知识,一般的Queue的使用方法poll(),take(),drainTo()和offer(),put()这些应该懂。
学习视频,可以丰富java知识。能够获得更多的专业技能
为了使用 DelayQueue,我们需要首先声明一个 Delayed 的对象,例如,我们可以声明一个 Task 对象, Task 对象实现了 Delayed 接口,用于表示一个具有延迟执行的任务。 ``` public class Task<T extends Runnable> ...
在Java的并发编程中,`DelayQueue`是一个非常特殊的队列,它属于并发包`java.util.concurrent`的一部分。`DelayQueue`是一个基于优先级队列(PriorityQueue)实现的无界阻塞队列,它的主要特性是元素只有在达到指定...
DelayQueue是一个无界阻塞队列,只有在延迟期满时,才能从中提取元素。它提供了在指定时间才能获取队列元素的功能,队列头元素是最接近过期的元素。DelayQueue的元素需要实现Delayed接口,该接口类定义如下: ...
下面是一个简单的使用`ScheduledExecutorService`实现延迟执行的Java代码示例: ```java import java.util.concurrent.*; public class DelayExecutionDemo { public static void main(String[] args) { // 创建...
volatile关键字的非原子性、volatile关键字的使用、AtomicInteger原子性操作、线程安全小例子:多个线程竞争问题、多个线程多个锁问题、创建一个缓存的线程池、多线程使用Vector或者HashTable的示例(简单线程同步...
4. 延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 SynchronousQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque ...
当一个线程调用 `acquire()` 方法时,如果当前可用的许可数量大于0,则减少一个许可并让该线程继续执行;如果许可数量为0,则该线程被挂起,等待其他线程释放许可。 - **应用场景**:在需要限制对某个资源的并发...
Unsafe 详细解Java SPI 机制详解Java语法糖详解集合知识点/面试题总结:Java集合常见知识点&面试题总结(上)(必看)Java集合常见知识点&面试题总结(下)(必看)Java容器使用注意事项总结源码分析:ArrayList核心...
例如,ArrayBlockingQueue 是一个有界的阻塞队列,它使用锁机制确保线程安全。然而,尽管 BlockingQueue 的基本操作是线程安全的,但像 `addAll`、`containsAll`、`retainAll` 和 `removeAll` 这样的批量操作并不...
Java并发库是Java SE 5.0引入的一个重要特性,它提供了很多高级并发工具,如线程池、同步容器、并发集合以及阻塞队列等,极大地简化了并发编程。 2. **阻塞队列(BlockingQueue)** 阻塞队列是一种特殊的队列,当...
`BlockingQueue` 是 `java.util.concurrent` 包中的一个接口,它扩展了传统的 `Queue` 接口,并引入了阻塞特性。这意味着当队列为空时,从队列中移除元素的操作将会阻塞;同样地,当队列满时,向队列添加元素的操作...
一个高效稳定的系统不仅能提高用户体验,还能降低运营成本,提升企业的竞争力。本文档旨在探讨Java企业版(Java EE)环境下性能调优的最佳实践,包括方法论、负载测试工具、软件栈中的各组件调优策略以及未来性能...
该项目是SpringBoot框架下的延迟...项目包含32个文件,涵盖24个Java源文件、4个XML配置文件、1个Git忽略文件、1个Markdown文件、1个YAML文件以及1个Spring Boot配置工厂文件,旨在简化延迟消息的实现和应用部署过程。
在"DelayQueueDemo.java"这个文件中,可能包含了一个示例程序,展示了如何创建一个Delayed对象并将其放入DelayQueue中。通常,这个示例会包含以下步骤: 1. 创建一个实现Delayed接口的类,例如`MyDelayedObject`,...
延迟队列 DelayQueue 5. 链阻塞队列 LinkedBlockingQueue 6. 具有优先级的阻塞队列 PriorityBlockingQueue 7. 同步队列 SynchronousQueue 8. 阻塞双端队列 BlockingDeque 9. 链阻塞双端队列 LinkedBlockingDeque 10...