URLStreamHandler.getHostAddress() performance

Peter Levart peter.levart at gmail.com
Thu Nov 27 20:17:32 UTC 2014


Hi,

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:

http://mail.openjdk.java.net/pipermail/net-dev/2014-July/008592.html

Regards, Peter

On 11/25/2014 03:03 PM, Mark Sheppard wrote:
> I think this raises  a more fundamental question, as to why   the URL 
> hashCode()  and equals() methods  delegates to URLStreamHandler
> in the first place? rather than performing the processing within the 
> URL class itself, and synchronizing appropriately within.
>
> If you call equals() and hasCode() concurrently on the same URL 
> instance, there exists the possibility (slight) that
> the hostAddress could be set differently, when it is being set for the 
> first time, without the synchronization of the getHostAddress() in the 
> URLStreamHandler.
>
> Although it may rarely happen the mechanics of InetAddress.getByName() 
> potentially,  lend itself to a different return address
> 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.
>
> regards
> Mark
>
> On 25/11/2014 12:58, Wang Weijun wrote:
>>> On Nov 25, 2014, at 20:25, Pavel Rappo <pavel.rappo at oracle.com> wrote:
>>>
>>> Hi Max,
>>>
>>> I don't see any particular reason for this. Maybe it's just a 
>>> "precaution". It seems to me it's the only field
>>> of the URL class set directly (without setter) from an outside.
>>>
>>> Does it hurt performance a lot? In what cases?
>> There is a 7x difference in my experiment on 
>> SecureClassLoader.defineClass().
>>
>> Or, it can be shown using this benchmark:
>>
>> package org.openjdk.bench;
>>
>> import org.openjdk.jmh.annotations.*;
>>
>> import java.io.IOException;
>> import java.net.URL;
>> import java.util.*;
>> import java.util.concurrent.ConcurrentHashMap;
>>
>> @State(Scope.Benchmark)
>> public class Weird {
>>      final int num = 100;
>>      final Object[] urls = new Object[num];
>>
>>      public static class CS {
>>          private final Object url;
>>          public CS(Object url) { this.url = url; }
>>          public int hashCode() { return url.hashCode(); }
>>          public boolean equals(Object o) { return o instanceof CS && 
>> url.equals(((CS)o).url); }
>>      }
>>
>>      private final Map<Object, Object> pdcacheC = new 
>> ConcurrentHashMap<>();
>>
>>      @Setup
>>      public void init() throws Exception {
>>          for (int i=0; i< num; i++) {
>>              urls[i] = new URL("file:/tmp/"+i);
>>          }
>>      }
>>
>>      @State(Scope.Thread)
>>      public static class ThreadState {
>>          final Random rand = new Random();
>>      }
>>
>>
>>      @Benchmark
>>      public void setC(ThreadState state) throws IOException {
>>          Object cs = new CS(urls[next(state)]);
>>          pdcacheC.computeIfAbsent(cs, x -> "");
>>      }
>>
>>      private int next(ThreadState state) {
>>          return state.rand.nextInt(num);
>>      }
>> }
>>
>> --Max
>>
>>
>>> -Pavel
>>>
>>>> On 25 Nov 2014, at 12:02, Wang Weijun <weijun.wang at oracle.com> wrote:
>>>>
>>>> I am benchmarking security manager and notice this
>>>>
>>>> protected synchronized InetAddress getHostAddress(URL u) {
>>>>    if (u.hostAddress != null)
>>>>        return u.hostAddress;
>>>>
>>>>    String host = u.getHost();
>>>>    if (host == null || host.equals("")) {
>>>>        return null;
>>>>    } else {
>>>>        try {
>>>>            u.hostAddress = InetAddress.getByName(host);
>>>>        } catch (UnknownHostException ex) {
>>>>            return null;
>>>>        } catch (SecurityException se) {
>>>>            return null;
>>>>        }
>>>>    }
>>>>    return u.hostAddress;
>>>> }
>>>>
>>>> Is there any reason why the method is synchronized? Why not simply 
>>>> "synchronized (u)"?
>>>>
>>>> Thanks
>>>> Max
>>>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/security-dev/attachments/20141127/ac1b7879/attachment-0001.html>


More information about the security-dev mailing list