简体   繁体   English

synchronized LinkedList - peek

[英]synchronized LinkedList - peek

A LinkedList has convenient peek , pop , ... methods. LinkedList方便的peekpop ,...方法。

Unfortunately, I need a thread-safe LinkedList . 不幸的是,我需要一个线程安全的LinkedList So, my first idea was to wrap it as follows: 所以,我的第一个想法是将它包装如下:

List<Object> list = Collections.synchronizedList(new LinkedList<>());

However, since the List interface does not contain the peek or pop methods. 但是,由于List接口不包含peekpop方法。 This doesn't work of course. 这当然不起作用。

Alternatively, I could use synchronized(list) blocks all over the code. 或者,我可以在整个代码中使用synchronized(list)块。 Is that the way to go ? 这是要走的路吗?

Any solutions that I'm overlooking ? 我忽视的任何解决方案?


EDIT: 编辑:

There are many reasons why one would use a LinkedList . 人们使用LinkedList原因有很多。 I see some people are proposing other collections. 我看到有些人提出了其他收藏品。 So, here follow the brief requirements, which lead to my decision of using a LinkedList . 所以,这里遵循简短的要求,这导致我决定使用LinkedList

More background information: 更多背景资料:

  • I'm using a LinkedList because the items need to be ordered. 我正在使用LinkedList,因为需要订购商品。
  • Items should be added in a non-blocking way. 应以非阻塞方式添加项目。
  • Items are added in the back ; 物品在后面添加; removed from the front. 从前面移除。
  • Before the first item is removed, it first needs to be peek ed and validated. 在删除第一个项目之前,首先需要peek并验证它。 If validation fails, then the item needs to stay in the list. 如果验证失败,则该项目需要保留在列表中。
  • Only if the validation completed successfully, then the first item is removed. 只有验证成功完成,才会删除第一个项目。
  • The queue needs to have a maximum size (to avoid memory issues). 队列需要具有最大大小(以避免内存问题)。

If you need peek to work, making a synchronized wrapper may not be sufficient, so you would have to write synchronized explicitly. 如果你需要peek工作,制作同步包装可能是不够的,所以你必须明确地写synchronized

It is not so much a problem with writing a wrapper as it is a problem with the semantic of the peek method. 编写包装器并不是一个问题,因为它是peek方法的语义问题。 Unlike the pop method, which represents a single action, peek method is often used in a multi-component action composed of peek -ing and then doing something else based on what peek returns. 与表示单个动作的pop方法不同, peek方法通常用于由peek -ing组成的多组件动作,然后根据peek返回的内容执行其他操作。

If you synchronize in a wrapper, the result would be the same as if you wrote this code manually: 如果在包装器中进行同步,结果将与手动编写此代码时的结果相同:

String s;
synchronized(list) {
    s = list.peek();
}
// <<== Problem ==>>
if (s != null) {
    synchronized(list) {
        s = list.pop();
    }
}

This presents a problem, because there is a moment in time when your list can change in between of peek and pop (this place in code above is marked as "Problem"). 这提出了一个问题,因为有一段时间你的列表可以在peekpop之间进行更改(上面代码中的这个地方被标记为“Problem”)。

A proper way to do check-and-modify is doing it in a single synchronized block, ie 检查和修改的正确方法是在单个synchronized块中进行,即

synchronized(list) {
    String s = list.peek();
    if (s != null) {
        s = list.pop();
    }
}

However, this cannot be done in a simple wrapper, because two list operations are performed in a single synchronized block. 但是,这不能在简单的包装器中完成,因为在单个synchronized块中执行了两个列表操作。

You can avoid writing synchronized in multiple places by building your own data structure that encapsulates a LinkedList<T> , and provides operations that perform all test-and-modify operations in a synchronized block. 您可以通过构建自己的封装LinkedList<T>的数据结构来避免在多个位置进行synchronized编写,并提供在同步块中执行所有测试和修改操作的操作。 This is not a simple problem, however, so you may be better off changing your algorithm in a way that it could work with one of pre-defined concurrent containers. 但是,这不是一个简单的问题,因此您最好以一种可以使用预定义并发容器之一的方式更改算法。

What you want is a concurrent Queue . 你想要的是并发Queue LinkedList implements List , Deque , and Queue . LinkedList实现ListDequeQueue The Queue is what gives it the FIFO (adding in back, remove from front) semantics with peek and pop. Queue是通过peek和pop赋予它FIFO(在后面添加,从前面删除)语义的原因。

A LinkedBlockingQueue can be bounded, which is one of your criteria. LinkedBlockingQueue可以是有界的,这是您的标准之一。 There are several other concurrent Queues and Deques to choose from as well. 还有其他几个并发队列和Deques可供选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM