在主线程中创建并传递到新线程的地图对象的正确同步

发布于 2024-10-13 06:27:13 字数 744 浏览 3 评论 0原文

我正在尝试开发一个程序,该程序接受对存储在地图中的数据的请求。该映射在 main 方法中声明,如下所示:

Map m = Collections.synchronizedMap(new HashMap());
synchronized(m) {
        while (listening) {

            new BrokerLookupServerHandlerThread(serverSocket.accept(), m).start();

        }
}

BrokerLookupServerHandlerThread 的代码获取输入并使其成为对象的变量之一。如果我在这个类中使用它,原始地图也会更新吗?我知道 Java 是按值传递的(我习惯了 C/C++),所以我只是想确定同步对象的这种实现是否有意义。

    private Socket socket = null;
//private String t ="MSFT";
public Map m;

public BrokerLookupServerHandlerThread(Socket socket, Map m) {
    super("NamingServerHandlerThread");
    this.socket = socket;
    this.m = m;
    System.out.println("Created new Thread to handle client");
}

感谢您的帮助。

I'm trying to develop a program that takes requests for data which is stored in a map. The map is declared in the main method as shown below:

Map m = Collections.synchronizedMap(new HashMap());
synchronized(m) {
        while (listening) {

            new BrokerLookupServerHandlerThread(serverSocket.accept(), m).start();

        }
}

The code for the BrokerLookupServerHandlerThread takes the input and makes it one of the object's variables. If I use it in this class, will the original map be updated as well? I understand that Java is pass by value, (I'm used to C/C++) so I just wanted to be sure if this implementation of a synchronized object makes sense.

    private Socket socket = null;
//private String t ="MSFT";
public Map m;

public BrokerLookupServerHandlerThread(Socket socket, Map m) {
    super("NamingServerHandlerThread");
    this.socket = socket;
    this.m = m;
    System.out.println("Created new Thread to handle client");
}

Thanks for your help.

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

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

发布评论

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

评论(2

苦笑流年记忆 2024-10-20 06:27:13

是的,原始对象将被更新。我建议您使用 ConcurrentHashMap尽管。

支持完整的哈希表
检索的并发性和
可调整的预期并发数
更新。这个类遵循同样的
功能规范为 Hashtable,
并包括方法的版本
对应每个方法
哈希表。然而,尽管所有
操作是线程安全的,
检索操作不需要锁定,并且不存在任何锁定
支持锁定整个表
以阻止所有访问的方式。
这个类是完全可互操作的
依赖于其的程序中的哈希表
线程安全但不在于其
同步详细信息。

Yes original object will be updated. I suggest you use ConcurrentHashMap though.

A hash table supporting full
concurrency of retrievals and
adjustable expected concurrency for
updates. This class obeys the same
functional specification as Hashtable,
and includes versions of methods
corresponding to each method of
Hashtable. However, even though all
operations are thread-safe,
retrieval operations do not entail locking, and there is not any
support for locking the entire table
in a way that prevents all access.
This class is fully interoperable with
Hashtable in programs that rely on its
thread safety but not on its
synchronization details.

栖竹 2024-10-20 06:27:13

是的,对地图所做的更改将被两个线程看到。

Java 确实使用按值传递 - 但本例中的值是一个引用(类似于指针)。 Java 中引用类型变量的值始终是对对象的引用,或者为 null。它从来都不是物体本身。

所以你的代码不会创建新的地图。隐式创建新对象的操作很少。我只能想到字符串文字的使用(无论如何文字都会被保留)和原始类型的自动装箱。除此之外,您只能通过 new 运算符获得一个新对象。 (显然,您调用的任何方法也可以创建一个新对象...)

请注意,这与线程之间的同步问题完全无关。复制对象与复制引用的业务与线程正交。在本例中,您似乎已经使用 Collections.synchronizedMap 解决了线程方面的问题;正如 Pangea 所说,您可能想使用 ConcurrentHashMap 来代替,它不会使用几乎那么多的锁定(如果有的话)。 ConcurrentMap 接口的另一个实现是 ConcurrentSkipListMap。查看两个课程的文档,以确定最适合您的课程。

Yes, changes made to the map will be seen by both threads.

Java does indeed use pass by value - but the value in this case is a reference (similar to a pointer). The value of a reference-type variable in Java is always a reference to an object, or null. It's never the object itself.

So your code won't create a new map. There are very few operations which implicitly create a new object. I can only think of the use of string literals (where the literals are interned anyway) and autoboxing of primitive types. Other than that, you'll only get a new object via the new operator. (Obviously any method you call could create a new object too...)

Note that this is entirely separate to the issue of synchronization between threads. The business about copying objects vs copying references is orthogonal to threading. In this case it looks like you've solved the threading aspect using Collections.synchronizedMap; as Pangea says you may want to use ConcurrentHashMap instead which won't use nearly as much locking (if any). Another implementation of the ConcurrentMap interface is ConcurrentSkipListMap. Look at the docs for both classes to decide what suits you best.

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