为 NavigableMap 编写同步线程安全包装器

发布于 2024-09-01 07:11:03 字数 2462 浏览 4 评论 0原文

java.util.Collections 目前提供以下实用方法来为各种集合接口创建同步包装器:

类似地,它也有 6 个 unmodifiedXXX 重载。

这里明显的遗漏是 的实用方法NavigableMap。确实,它扩展了 SortedMap,但 SortedSet 扩展了 SetSet 扩展了 Collection 以及 Collections 也扩展了SortedSetSet 的专用实用方法。据推测,NavigableMap 是一个有用的抽象,否则它一开始就不会存在,但还没有针对它的实用方法。

所以问题是:

  • Collections 不为 NavigableMap 提供实用方法是否有特定原因?
  • 您将如何为 NavigableMap 编写自己的 synchronized 包装器?
    • 浏览OpenJDK 版本 Collections.java 的源代码似乎表明这只是一个“机械”过程
      • 一般来说,您真的可以添加这样的同步线程安全功能吗?
      • 如果这是一个机械过程,可以自动化吗? (Eclipse插件等)
      • 此代码重复是否必要,或者可以通过不同的 OOP 设计模式来避免吗?

java.util.Collections currently provide the following utility methods for creating synchronized wrapper for various collection interfaces:

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 for NavigableMap?
  • How would you write your own synchronized wrapper for NavigableMap?
    • 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

好倦 2024-09-08 07:11:03

这是一个疏忽。 修复是在 Java 8 中添加的。

乔什写道:

“他们绝对属于那里。他们的缺席是无意的。
我们应该尽快把它们放进去。”

我同意,尽管我们工程师都没有期待
编写(和测试)所有那些令人头脑麻木的转发方法。
发布日期:2006-08-21 00:50:41.0


如果您还没有使用 Java 8,您可以考虑劫持 java.util 包,因为您想扩展 静态类 SynchronizedSortedMap 被声明为包私有。否则就会有大量的代码复制粘贴。首先是:

package java.util;

import java.util.Collections.SynchronizedSortedMap;

public class NewCollections {

    public static <K, V> NavigableMap<K, V> synchronizedNavigableMap(NavigableMap<K, V> m) {
        return new SynchronizedNavigableMap<K, V>(m);
    }

    static class SynchronizedNavigableMap<K, V> extends SynchronizedSortedMap<K, V> implements NavigableMap<K, V> {
        private final NavigableMap<K, V> sm;

        SynchronizedNavigableMap(NavigableMap<K, V> m) {
            super(m);
            sm = m;
        }

        SynchronizedNavigableMap(NavigableMap<K, V> m, Object mutex) {
            super(m, mutex);
            sm = m;
        }

    }
}

让 IDE 自动生成 NavigableMap 的未实现方法,并以与 SynchronizedSortedMap 相同的方式对其进行编码。这是一个示例:

        @Override
        public K ceilingKey(K key) {
            synchronized (mutex) { return sm.ceilingKey(key); }
        }

请注意,返回 Set 的方法也需要将其包装在 SynchronizedSet 中。再次,请参阅 SynchronizedMapSynchronizedSortedMap 来源以获得见解:)

我不认为它是(能够)一个机械过程,因为它涉及很多因素。

This was an oversight. The fix was added in Java 8.

Josh writes:

"They definitely belong there. Their absence is unintentional.
We should put them in as soon as possible."

I agree, even though none of us engineers are looking forward
to writing (and testing) all those mind-numbing forwarding methods.
Posted Date : 2006-08-21 00:50:41.0


In case you're not on Java 8 yet, you may consider to hijack the java.util package since you would like to extend static class SynchronizedSortedMap<K, V> which is declared package private. Else it's going to be a lot of code copypaste. Here's a kickoff:

package java.util;

import java.util.Collections.SynchronizedSortedMap;

public class NewCollections {

    public static <K, V> NavigableMap<K, V> synchronizedNavigableMap(NavigableMap<K, V> m) {
        return new SynchronizedNavigableMap<K, V>(m);
    }

    static class SynchronizedNavigableMap<K, V> extends SynchronizedSortedMap<K, V> implements NavigableMap<K, V> {
        private final NavigableMap<K, V> sm;

        SynchronizedNavigableMap(NavigableMap<K, V> m) {
            super(m);
            sm = m;
        }

        SynchronizedNavigableMap(NavigableMap<K, V> m, Object mutex) {
            super(m, mutex);
            sm = m;
        }

    }
}

Let the IDE autogenerate the unimplemented methods of NavigableMap and code them the same way as SynchronizedSortedMap does. Here's ONE example:

        @Override
        public K ceilingKey(K key) {
            synchronized (mutex) { return sm.ceilingKey(key); }
        }

Note that the methods which returns for example Set you'll need to wrap it in SynchronizedSet as well. Again, see the SynchronizedMap and SynchronizedSortedMap sources for insights :)

I don't expect it to be (able to be) a mechanical process since it involves a lot of factors.

难忘№最初的完美 2024-09-08 07:11:03

一般来说你可以添加吗?
同步线程安全特性
像这样吗?

我相信这是真的。线程安全的定义是(IMO),

如果从多线程调用时没有任何不正确的行为(从单个线程使用时不会发生)可以发生在它的所有方法上,则该类是线程安全的。外部同步。

现在,下面的代码将确保“Something”永远不会被多个线程调用,对吗?因此,我相信不会因为被多线程调用而出现不良行为;它永远不会从多个线程调用!

这可能也是EJB 背后的想法。无状态 EJB 永远不会被多个线程调用(由容器强制执行)。这就是为什么 EJB 规范可以说“您不必担心线程安全”。

public class MakeSomethingThreadSafe implements Something {
    private final Object lock = new Object();
    private final Something subject;

    public MakeSomethingThreadSafe(Something subject){
        this.subject = subject;
    }

    public void someMethod(){
        synchronized(lock){
            subject.someMethod();
        }
    }
}

或者我错过了什么?

为了使帖子完整:

有什么具体原因吗
集合不提供实用性
NavigableMap 的方法?

我同意斯蒂芬的观点。

你会如何写自己的
NavigableMap 的同步包装器?

就像我的示例代码一样..

一般来说你可以添加吗?
同步线程安全特性
像这样?如果是这样的机械
流程,能自动化吗? (蚀
插件等)

是的,我认为它可以很容易地实现自动化。

  1. 实现接口
  2. Make 2字段;一种用于互斥锁,一种用于主题。
  3. 创建一个构造函数来注入主题。
  4. 使每个方法同步并委托给主题。

此代码是否需要重复,或者
它可以被避免吗
不同的OOP设计模式?

比如 SetMap 等?对我来说,以“正常”方式解决这个问题似乎不可能。

Is it true that in general you can add
synchronized thread-safetiness feature
like this?

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".

public class MakeSomethingThreadSafe implements Something {
    private final Object lock = new Object();
    private final Something subject;

    public MakeSomethingThreadSafe(Something subject){
        this.subject = subject;
    }

    public void someMethod(){
        synchronized(lock){
            subject.someMethod();
        }
    }
}

Or am I missing something?

To make the post complete:

Is there a specific reason why
Collections doesn't provide utility
methods for NavigableMap?

I agree with Stephen.

How would you write your own
synchronized wrapper for NavigableMap?

Like my sample code..

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)

Yeah I think it can easily be automated.

  1. Implement the interface
  2. Make 2 fields; One for the mutex, one for the subject.
  3. Create a constructor to inject subject.
  4. Make every method synchronized and delegate to subject.

Is this code repetition necessary, or
could it have been avoided by a
different OOP design pattern?

Like for Set, Map etc? It doesn't sound possible to me to solve it in a "normal" way..

旧人哭 2024-09-08 07:11:03

仅供参考,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

眼中杀气 2024-09-08 07:11:03

Collections 不为 NavigableMap 提供实用方法有什么具体原因吗?

我想不出具体的原因。这要么是

  • 一个疏忽,
  • 要么是“几乎没有人会使用它”的情况,要么
  • 可能存在一些不明显的技术困难。

但无论哪种情况,原因并不重要。实用方法不存在,所以要么找第三方库,要么自己实现。

一般来说,您是否可以像这样添加同步线程安全功能?

一般来说没有。您需要了解所绑定的类的语义,以确保线程安全,以确定包装器是否足够。

如果是这样一个机械过程,可以自动化吗? (Eclipse插件等)

否...见上文。

此代码重复是否必要,或者是否可以通过不同的 OOP 设计模式来避免?

我认为这是无法避免的。一般来说,这种事情需要对元编程或编写包装类的特定情况的语言支持。设计模式不会为你做那样的事情。

Is there a specific reason why Collections doesn't provide utility methods for NavigableMap?

I cannot think of a specific reason. It is either

  • an oversight,
  • a case of "hardly anyone would use it", or
  • maybe there is some technical difficulty that is not obvious.

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.

Is it true that in general you can add synchronized thread-safetyness feature like this?

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.

If it's such a mechanical process, can it be automated? (Eclipse plug-in, etc)

No ... see above.

Is this code repetition necessary, or could it have been avoided by a different OOP design pattern?

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文