在主线程中创建并传递到新线程的地图对象的正确同步
我正在尝试开发一个程序,该程序接受对存储在地图中的数据的请求。该映射在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,原始对象将被更新。我建议您使用 ConcurrentHashMap尽管。
Yes original object will be updated. I suggest you use ConcurrentHashMap though.
是的,对地图所做的更改将被两个线程看到。
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 useConcurrentHashMap
instead which won't use nearly as much locking (if any). Another implementation of theConcurrentMap
interface isConcurrentSkipListMap
. Look at the docs for both classes to decide what suits you best.