我有一个get-method返回非基本类型,应该是线程安全的。
功能描述
我有一个操作在一个单独的线程上。此操作需要IP地址并使用我自己的getter方法从其他类获取它(因为我必须进行一些IP地址计算)。 getter返回InetAddress
。
代码示例
// This is called in a separate thread.
// How can I make Utility.getMyIp() thread-safe?
InetAddress myIp = Utility.getMyIp();
问题
关于IP-Address getter方法,我需要注意什么?我需要从其他线程使用该方法。我必须让它同步吗?
如果您需要更多信息,请询问!
PS:还有其他线程提出类似的问题,但我发现的那些只讨论原始数据类型,应该足以使用易失性关键字。在这里,我需要返回一个类型InetAddress
。
编辑:添加代码
这是正在进行的工作(它可能不适用于所有情况,也不是完成代码)。
/**
* Gets the BroadcastAddress for IPv4.
* @return
* @throws SocketException
*/
public static InetAddress getBroadcastAddress4() {
// Todo: Check other possibility
System.setProperty("java.net.preferIPv4Stack" , "true");
// Init
InetAddress broadcastAddress = null;
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while(interfaces != null && interfaces.hasMoreElements()){
NetworkInterface currentInterface = interfaces.nextElement();
if(!currentInterface.isLoopback()){
for(InterfaceAddress address : currentInterface.getInterfaceAddresses()){
InetAddress broadcast = address.getBroadcast();
if(broadcast != null){
broadcastAddress = broadcast;
break;
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return broadcastAddress;
}
答案 0 :(得分:1)
代码是线程安全的,无需任何进一步修改。
您还可以将此方法的结果存储到变量中并执行一次实际计算 - 因为在程序运行期间结果不太可能发生变化。懒惰地初始化变量或使用static {}
代码块在classload上初始化它。代码可能如下所示:
InetAddress broadcastAddress;
public static InetAddress getBroadcastAddress4() {
return broadcastAddress;
}
static {
System.setProperty("java.net.preferIPv4Stack" , "true");
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while(interfaces != null && interfaces.hasMoreElements()){
NetworkInterface currentInterface = interfaces.nextElement();
if(!currentInterface.isLoopback()){
for(InterfaceAddress address : currentInterface.getInterfaceAddresses()){
InetAddress broadcast = address.getBroadcast();
if(broadcast != null){
broadcastAddress = broadcast;
break;
}
}
}
}
} catch (SocketException e) {
// log the damn exception!
Logger.getLogger(YourClass.class).error("exception when getting broadcast address", e);
}
}
答案 1 :(得分:0)
如果在单个实例中存在实现get
方法的对象,则在getter方法声明之前的synchronized
关键字就足够了。
您也可以使用同步集合(如ConcurrentHashMap)来存储和访问您的数据。
然而,有可能存在更有效的解决方案。与所有多线程同步一样,您必须识别并隔离关键部分。通常临界区越短,代码的速度就越快。答案 2 :(得分:0)
据我所知,您的代码是线程安全的,因此这里不需要额外的工作。您没有使用可以沿线程共享的共享可变资源,所以在这里应该没有问题。