为 NavigableMap 编写同步线程安全包装器
java.util.Collections
目前提供以下实用方法来为各种集合接口创建同步
包装器:
synchronizedCollection(Collection
c) synchronizedList(List
;列表) synchronizedMap(Map
m) synchronizedSet(Set
; s) synchronizedSortedMap(SortedMap
m) synchronizedSortedSet(SortedSet
s)
类似地,它也有 6 个 unmodifiedXXX
重载。
这里明显的遗漏是 的实用方法NavigableMap
。确实,它扩展了 SortedMap
,但 SortedSet 扩展了 Set
、Set 扩展了 Collection
以及 Collections
也扩展了SortedSet
和 Set
的专用实用方法。据推测,NavigableMap
是一个有用的抽象,否则它一开始就不会存在,但还没有针对它的实用方法。
所以问题是:
Collections
不为NavigableMap
提供实用方法是否有特定原因?- 您将如何为
NavigableMap
编写自己的synchronized
包装器?- 浏览OpenJDK 版本
Collections.java
的源代码似乎表明这只是一个“机械”过程- 一般来说,您真的可以添加这样的
同步
线程安全功能吗? - 如果这是一个机械过程,可以自动化吗? (Eclipse插件等)
- 此代码重复是否必要,或者可以通过不同的 OOP 设计模式来避免吗?
- 一般来说,您真的可以添加这样的
- 浏览OpenJDK 版本
java.util.Collections
currently provide the following utility methods for creating synchronized
wrapper for various collection interfaces:
synchronizedCollection(Collection<T> c)
synchronizedList(List<T> list)
synchronizedMap(Map<K,V> m)
synchronizedSet(Set<T> s)
synchronizedSortedMap(SortedMap<K,V> m)
synchronizedSortedSet(SortedSet<T> s)
Analogously, it also has 6 unmodifiedXXX
overloads.
The glaring omission here are the utility methods for NavigableMap<K,V>
. It's true that it extends SortedMap
, but so does SortedSet extends Set
, and Set extends Collection
, and Collections
have dedicated utility methods for SortedSet
and Set
. Presumably NavigableMap
is a useful abstraction, or else it wouldn't have been there in the first place, and yet there are no utility methods for it.
So the questions are:
- Is there a specific reason why
Collections
doesn't provide utility methods forNavigableMap
? - How would you write your own
synchronized
wrapper forNavigableMap
?- Glancing at the source code for OpenJDK version of
Collections.java
seems to suggest that this is just a "mechanical" process- Is it true that in general you can add
synchronized
thread-safetiness feature like this? - If it's such a mechanical process, can it be automated? (Eclipse plug-in, etc)
- Is this code repetition necessary, or could it have been avoided by a different OOP design pattern?
- Is it true that in general you can add
- Glancing at the source code for OpenJDK version of
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个疏忽。 修复是在 Java 8 中添加的。
如果您还没有使用 Java 8,您可以考虑劫持
java.util
包,因为您想扩展静态类 SynchronizedSortedMap
被声明为包私有。否则就会有大量的代码复制粘贴。首先是:让 IDE 自动生成
NavigableMap
的未实现方法,并以与SynchronizedSortedMap
相同的方式对其进行编码。这是一个示例:请注意,返回
Set
的方法也需要将其包装在SynchronizedSet
中。再次,请参阅SynchronizedMap
和SynchronizedSortedMap
来源以获得见解:)我不认为它是(能够)一个机械过程,因为它涉及很多因素。
This was an oversight. The fix was added in Java 8.
In case you're not on Java 8 yet, you may consider to hijack the
java.util
package since you would like to extendstatic class SynchronizedSortedMap<K, V>
which is declared package private. Else it's going to be a lot of code copypaste. Here's a kickoff:Let the IDE autogenerate the unimplemented methods of
NavigableMap
and code them the same way asSynchronizedSortedMap
does. Here's ONE example:Note that the methods which returns for example
Set
you'll need to wrap it inSynchronizedSet
as well. Again, see theSynchronizedMap
andSynchronizedSortedMap
sources for insights :)I don't expect it to be (able to be) a mechanical process since it involves a lot of factors.
我相信这是真的。线程安全的定义是(IMO),
如果从多线程调用时没有任何不正确的行为(从单个线程使用时不会发生)可以发生在它的所有方法上,则该类是线程安全的。外部同步。
现在,下面的代码将确保“Something”永远不会被多个线程调用,对吗?因此,我相信不会因为被多线程调用而出现不良行为;它永远不会从多个线程调用!
这可能也是EJB 背后的想法。无状态 EJB 永远不会被多个线程调用(由容器强制执行)。这就是为什么 EJB 规范可以说“您不必担心线程安全”。
或者我错过了什么?
为了使帖子完整:
我同意斯蒂芬的观点。
就像我的示例代码一样..
是的,我认为它可以很容易地实现自动化。
比如
Set
、Map
等?对我来说,以“正常”方式解决这个问题似乎不可能。I believe that is true. The definition of thread safety is (IMO),
A class is thread-safe if no incorrect behavior (that cannot occur when used from a single thread) can occur for all methods of it, when called from multiple-threads without any external synchronization.
Now, below code will ensure that "Something" is never called by multiple threads, right? Therefore, I believe no adverse behavior can emerge because of being called by multiple threads; It's never called from multiple threads!
This is probably also the idea behind EJB. Stateless EJBs are never called by more than one thread (enforced by the container). This is why the EJB spec can say "You don't have to worry about thread-safety".
Or am I missing something?
To make the post complete:
I agree with Stephen.
Like my sample code..
Yeah I think it can easily be automated.
Like for
Set
,Map
etc? It doesn't sound possible to me to solve it in a "normal" way..仅供参考,Java 8 现在拥有它:
private NavigableMap地图 = Collections.synchronizedNavigableMap(...);
请参阅 Navigable Map 上的 Java8 文档
FYI, Java 8 now have it:
private NavigableMap<Date,T> map = Collections.synchronizedNavigableMap(...);
Please see the Java8 Doc on Navigable Map
我想不出具体的原因。这要么是
但无论哪种情况,原因并不重要。实用方法不存在,所以要么找第三方库,要么自己实现。
一般来说没有。您需要了解所绑定的类的语义,以确保线程安全,以确定包装器是否足够。
否...见上文。
我认为这是无法避免的。一般来说,这种事情需要对元编程或编写包装类的特定情况的语言支持。设计模式不会为你做那样的事情。
I cannot think of a specific reason. It is either
But in either case, the reason doesn't really matter. The utility method is not there, so either you find a third-party library or implement it yourself.
In general no. You need to understand the semantics of the class you are tying to make thread safe to figure out whether a wrapper is sufficient.
No ... see above.
I don't think that it is avoidable. This kind of thing would require linguistic support for meta-programming in general, or for the specific case of writing wrapper classes. Design patterns don't do that kind of thing for you.