我正在尝试开发一个程序来接收存储在地图中的数据请求。地图在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");
}
感谢您的帮助。
答案 0 :(得分:1)
是的,两个线程都会看到对地图所做的更改。
Java确实使用pass by value - 但在这种情况下,值是一个引用(类似于指针)。 Java中引用类型变量的值始终是对象的引用,或者为null。它永远不是对象本身。
因此您的代码不会创建新地图。很少有操作隐式创建新对象。我只能想到使用字符串文字(无论如何都是文字内容)和原始类型的自动装箱。除此之外,您只能通过new
运算符获取新对象。 (显然你调用的任何方法都可以创建一个新对象......)
请注意,这与线程之间的同步问题完全不同。有关复制对象与复制引用的业务与线程正交。在这种情况下,您似乎已使用Collections.synchronizedMap
解决了线程方面问题;正如Pangea所说,您可能希望使用ConcurrentHashMap
而不会使用几乎同样多的锁定(如果有的话)。 ConcurrentMap
接口的另一个实现是ConcurrentSkipListMap
。查看两个课程的文档,以确定最适合您的课程。
答案 1 :(得分:1)
是原始对象将被更新。我建议您使用ConcurrentHashMap。
支持完整的哈希表 检索和并发 可调节的预期并发性 更新。这门课也服从同样的道理 功能规范为Hashtable, 并包括方法的版本 对应于每种方法 哈希表。但是,尽管如此 操作是线程安全的, 检索操作不需要锁定,也没有 支持锁定整个表 以阻止所有访问的方式。 这个类可以完全互操作 Hashtable在依赖于它的程序中 线程安全,但没有 同步细节。