如何使用ConcurrentLinkedQueue? [英] How to use ConcurrentLinkedQueue?

查看:218
本文介绍了如何使用ConcurrentLinkedQueue?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在Java中使用 ConcurrentLinkedQueue

使用此 LinkedQueue 我需要担心队列中的并发性?或者,我只需要定义两个方法(一个从列表中搜索元素,另一个添加元素到列表)?

注意:显然这两个方法必须同步。对吗?

How do I use a ConcurrentLinkedQueue in Java?
Using this LinkedQueue, do I need to be worried about concurrency in the queue? Or do I just have to define two methods (one to retrive elements from the list and another to add elements to the list)?
Note: obviously these two methods have to be synchronized. Right?

编辑:我想要做的是:类(在Java中)使用一个方法从队列中检索项目,另一个类使用一个方法将项目添加到队列中。

What I'm trying to do is this: I have a class (in Java) with one method to retrieve items from the queue and another class with one method to add items to the queue. The items added and retrieved from the list are objects of my own class.

另一个问题:我需要在remove方法中执行此操作:

One more question: do I need to do this in the remove method:

while (queue.size() == 0){ 
  wait(); 
  queue.poll();
}

我只有一个消费者和一个生产者。

I only have one consumer and one producer.

推荐答案

不,这些方法不需要同步,你不需要定义任何方法;它们已经在ConcurrentLinkedQueue中,只是使用它们。 ConcurrentLinkedQueue执行所有的锁定和内部你需要的东西;

No, the methods don't need to be synchronized, and you don't need to define any methods; they are already in ConcurrentLinkedQueue, just use them. ConcurrentLinkedQueue does all the locking and stuff you need internally; your producer(s) just offer stuff into the queue, and your consumers poll for it.

首先,创建队列:

Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();

现在,无论你创建你的生产者/消费者对象,传入队列,放置他们的对象(你可以使用setter为此,相反,但我喜欢在构造函数中做这样的事情):

Now, wherever you are creating your producer/consumer objects, pass in the queue so they have somewhere to put their objects (you could use a setter for this, instead, but I prefer to do this kind of thing in a constructor):

YourProducer producer = new YourProducer(queue);

和:

YourConsumer consumer = new YourConsumer(queue);

并在制作人中添加内容:

and add stuff to it in your producer:

queue.offer(myObject);

并在消费者中取出东西(如果队列为空,所以检查它):

and take stuff out in your consumer (if the queue is empty, poll() will return null, so check it):

YourObject myObject = queue.poll();

有关详情,请参阅 Javadoc

如果你需要阻塞等待队列不为空,你可能想使用 LinkedBlockingQueue ,并使用take()方法。但是,LinkedBlockingQueue具有最大容量(默认值为Integer.MAX_VALUE,超过20亿),因此根据您的情况可能不合适。

If you need to block waiting for the queue to not be empty, you probably want to use a LinkedBlockingQueue, and use the take() method. However, LinkedBlockingQueue has a maximum capacity (defaults to Integer.MAX_VALUE, which is over two billion) and thus may or may not be appropriate depending on your circumstances.

如果您只有一个线程将东西放入队列,另一个线程从队列中取出东西,ConcurrentLinkedQueue可能是过度的。更重要的是,当你可能有数百甚至数千个线程同时访问队列时。您的需求可能会通过使用:

If you only have one thread putting stuff into the queue, and another thread taking stuff out of the queue, ConcurrentLinkedQueue is probably overkill. It's more for when you may have hundreds or even thousands of threads accessing the queue at the same time. Your needs will probably be met by using:

Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());

此外,它还锁定在实例(队列)以确保复合操作的原子性(如Jared解释)。你不能使用ConcurrentLinkedQueue这样做,因为所有操作都是在实例上使用不锁定(使用java.util.concurrent.atomic变量)。如果你想在队列为空时阻塞而不需要这样做,因为poll()将只是返回null,而队列是空的,而poll()是原子的。检查poll()是否返回null。如果是,wait(),然后重试。不需要锁定。

A plus of this is that it locks on the instance (queue), so you can synchronize on queue to ensure atomicity of composite operations (as explained by Jared). You CANNOT do this with a ConcurrentLinkedQueue, as all operations are done WITHOUT locking on the instance (using java.util.concurrent.atomic variables). You will NOT need to do this if you want to block while the queue is empty, because poll() will simply return null while the queue is empty, and poll() is atomic. Check to see if poll() returns null. If it does, wait(), then try again. No need to lock.

老实说,我只是使用LinkedBlockingQueue。它仍然是overkill为您的应用程序,但赔率是它会工作正常。如果它不够高性能(PROFILE!),你总是可以尝试别的东西,这意味着你不必处理任何同步的东西:

Honestly, I'd just use a LinkedBlockingQueue. It is still overkill for your application, but odds are it will work fine. If it isn't performant enough (PROFILE!), you can always try something else, and it means you don't have to deal with ANY synchronized stuff:

BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();

queue.put(myObject); // Blocks until queue isn't full.

YourObject myObject = queue.take(); // Blocks until queue isn't empty.

其他都是一样的。放置可能不会阻止,因为你不太可能把二十亿个对象放入队列。

Everything else is the same. Put probably won't block, because you aren't likely to put two billion objects into the queue.

这篇关于如何使用ConcurrentLinkedQueue?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆