题目:有两个线程A,B, A线程每200ms就生成一个[0,100]之间的随机数, B线程每2S中打印出A线程所产生的增量随机数。
一、采用阻塞队列来做。
public class TestBlockingQueue {
static BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
public static void main(String[] args) {
ScheduledExecutorService thread = Executors.newScheduledThreadPool(2);
final Random random = new Random();
thread.scheduleAtFixedRate(new Runnable() {
public void run() {
int value = random.nextInt(101);
queue.offer(value);// 此处用add方法会出问题,之后队列全部为空,添加元素失败。
}
}, 0, 200, TimeUnit.MILLISECONDS);
thread.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
List list = new ArrayList<>();
try {
System.out.println(queue.size());
queue.drainTo(list);
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
}
}
}, 2000, 2000, TimeUnit.MILLISECONDS);
}
}
注意:注释处使用add方法,只能添加一次队列(填充满),之后队列会为空,添加元素失败,根据api来看:
add:Inserts the specified element at the specified position in this list
将指定的元素插入到list中指定的的位置。
offer:Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions.
如果在不违反容量限制的情况下,尽可能快的将指定的元素插入到queue中去。
猜测可能在队列清空时,指针并没有回到队列头部,导致添加元素的位置超过了队列长度,最终添加失败。(待证实)
二、BlockingQueue中部分API介绍
offer(E e): 将给定的元素设置到队列中,如果设置成功返回true, 否则返回false. e的值不能为空,否则抛出空指针异常。
offer(E e, long timeout, TimeUnit unit): 将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false.
add(E e): 将给定元素设置到队列中,如果设置成功返回true, 否则抛出异常。如果是往限定了长度的队列中设置值,推荐使用offer()方法。
put(E e): 将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,直到队列中有多余的空间。
take(): 从队列中获取值,如果队列中没有值,线程会一直阻塞,直到队列中有值,并且该方法取得了该值。
poll(long timeout, TimeUnit unit): 在给定的时间里,从队列中获取值,如果没有取到会抛出异常。
remainingCapacity():获取队列中剩余的空间。
remove(Object o): 从队列中移除指定的值。
contains(Object o): 判断队列中是否拥有该值。
drainTo(Collection c): 将队列中值,全部移除,并发设置到给定的集合中。