<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body style="background-color: rgb(255, 255, 255); color: rgb(0, 0,
0);" text="#000000" bgcolor="#FFFFFF">
Hi,<br>
<br>
Some time ago I dived into the sinchronization pitfalls of URL /
URLStreamHandler and came up with a possible solution. Here's the
thread (mostly just my comments) and a patch:<br>
<br>
<a class="moz-txt-link-freetext" href="http://mail.openjdk.java.net/pipermail/net-dev/2014-July/008592.html">http://mail.openjdk.java.net/pipermail/net-dev/2014-July/008592.html</a><br>
<br>
Regards, Peter<br>
<br>
<div class="moz-cite-prefix">On 11/25/2014 03:03 PM, Mark Sheppard
wrote:<br>
</div>
<blockquote cite="mid:54748C22.9030109@oracle.com" type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900; padding: 0px 15px; margin: 2px 0px;"><![endif]-->I
think this raises a more fundamental question, as to why the
URL hashCode() and equals() methods delegates to
URLStreamHandler
<br>
in the first place? rather than performing the processing within
the URL class itself, and synchronizing appropriately within.
<br>
<br>
If you call equals() and hasCode() concurrently on the same URL
instance, there exists the possibility (slight) that
<br>
the hostAddress could be set differently, when it is being set for
the first time, without the synchronization of the
getHostAddress() in the URLStreamHandler.
<br>
<br>
Although it may rarely happen the mechanics of
InetAddress.getByName() potentially, lend itself to a different
return address
<br>
on multiple calls, as it returns the first address from a array of
addresses retrieved - assumption is that the ordering will always
be the same.
<br>
<br>
regards
<br>
Mark
<br>
<br>
On 25/11/2014 12:58, Wang Weijun wrote:
<br>
<blockquote type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900; padding: 0px 15px; margin: 2px 0px;"><![endif]-->
<blockquote type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900; padding: 0px 15px; margin: 2px 0px;"><![endif]-->On
Nov 25, 2014, at 20:25, Pavel Rappo
<a class="moz-txt-link-rfc2396E" href="mailto:pavel.rappo@oracle.com"><pavel.rappo@oracle.com></a> wrote:
<br>
<br>
Hi Max,
<br>
<br>
I don't see any particular reason for this. Maybe it's just a
"precaution". It seems to me it's the only field
<br>
of the URL class set directly (without setter) from an
outside.
<br>
<br>
Does it hurt performance a lot? In what cases?
<br>
<!--[if !IE]></DIV><![endif]--></blockquote>
There is a 7x difference in my experiment on
SecureClassLoader.defineClass().
<br>
<br>
Or, it can be shown using this benchmark:
<br>
<br>
package org.openjdk.bench;
<br>
<br>
import org.openjdk.jmh.annotations.*;
<br>
<br>
import java.io.IOException;
<br>
import java.net.URL;
<br>
import java.util.*;
<br>
import java.util.concurrent.ConcurrentHashMap;
<br>
<br>
@State(Scope.Benchmark)
<br>
public class Weird {
<br>
final int num = 100;
<br>
final Object[] urls = new Object[num];
<br>
<br>
public static class CS {
<br>
private final Object url;
<br>
public CS(Object url) { this.url = url; }
<br>
public int hashCode() { return url.hashCode(); }
<br>
public boolean equals(Object o) { return o instanceof
CS && url.equals(((CS)o).url); }
<br>
}
<br>
<br>
private final Map<Object, Object> pdcacheC = new
ConcurrentHashMap<>();
<br>
<br>
@Setup
<br>
public void init() throws Exception {
<br>
for (int i=0; i< num; i++) {
<br>
urls[i] = new URL(<a class="moz-txt-link-rfc2396E" href="file:/tmp/">"file:/tmp/"</a>+i);
<br>
}
<br>
}
<br>
<br>
@State(Scope.Thread)
<br>
public static class ThreadState {
<br>
final Random rand = new Random();
<br>
}
<br>
<br>
<br>
@Benchmark
<br>
public void setC(ThreadState state) throws IOException {
<br>
Object cs = new CS(urls[next(state)]);
<br>
pdcacheC.computeIfAbsent(cs, x -> "");
<br>
}
<br>
<br>
private int next(ThreadState state) {
<br>
return state.rand.nextInt(num);
<br>
}
<br>
}
<br>
<br>
--Max
<br>
<br>
<br>
<blockquote type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900; padding: 0px 15px; margin: 2px 0px;"><![endif]-->-Pavel
<br>
<br>
<blockquote type="cite"><!--[if !IE]><DIV style="border-left: 2px solid #009900; border-right: 2px solid #009900; padding: 0px 15px; margin: 2px 0px;"><![endif]-->On
25 Nov 2014, at 12:02, Wang Weijun
<a class="moz-txt-link-rfc2396E" href="mailto:weijun.wang@oracle.com"><weijun.wang@oracle.com></a> wrote:
<br>
<br>
I am benchmarking security manager and notice this
<br>
<br>
protected synchronized InetAddress getHostAddress(URL u) {
<br>
if (u.hostAddress != null)
<br>
return u.hostAddress;
<br>
<br>
String host = u.getHost();
<br>
if (host == null || host.equals("")) {
<br>
return null;
<br>
} else {
<br>
try {
<br>
u.hostAddress = InetAddress.getByName(host);
<br>
} catch (UnknownHostException ex) {
<br>
return null;
<br>
} catch (SecurityException se) {
<br>
return null;
<br>
}
<br>
}
<br>
return u.hostAddress;
<br>
}
<br>
<br>
Is there any reason why the method is synchronized? Why not
simply "synchronized (u)"?
<br>
<br>
Thanks
<br>
Max
<br>
<br>
<!--[if !IE]></DIV><![endif]--></blockquote>
<!--[if !IE]></DIV><![endif]--></blockquote>
<!--[if !IE]></DIV><![endif]--></blockquote>
<br>
<!--[if !IE]></DIV><![endif]--></blockquote>
<br>
</body>
</html>