jena-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andy Seaborne <a...@apache.org>
Subject Re: IRIResolver cache not thread safe?
Date Thu, 03 Nov 2011 08:14:17 GMT
On 02/11/11 20:06, Simon Helsen wrote:

> However, independent of that, when I look at IRIResolverNormal, it has a
> cache
>
> *private*Cache<String, IRI> resolvedIRIs=
> CacheFactory./createCache/(getter, /CacheSize/) ;
>
> which is not thread-safe. So *public*IRI resolveSilent(String
> relURI)could not be used from multiple threads.
>
> @Andy: are you saying that access to resolveSilent is definitely
> single-threaded, even if there are multiple concurrent reads?

.resolveSilent is an object method - it is not called from separate 
threads without an outer lock.

Each parser run creates a Prologue object which includes a prefix map 
and a resolver, and the also the bNode label mapping.

It's is only for the life time of the RIOT parser (not the jena reader) 
and a new one if created for each parse run so they are are not 
multithread - they have a handle on the input stream to be parsed for 
example.  There is no need to lock.

There is also a static instance of IRIResolverNormal inside IRIResolver 
(there is no route to getting hold of the object directly) and every 
static method that accesses it is synchronized.  It is created in class 
initialization.

e.g.

    static private IRI resolveIRI(String relStr, String baseStr)
     {
         synchronized(globalResolverLock)
         {
             IRI i = iriFactory.create(relStr);
             if (i.isAbsolute())
                 // removes excess . segments
                 return globalResolver.getBaseIRI().create(i);

             IRI base = iriFactory.create(baseStr);

             if ("file".equalsIgnoreCase(base.getScheme()))
                 return globalResolver.getBaseIRI().create(i);
             return base.create(i);
         }
     }

IRIResolverNormal is a static inner class with resolvedIRIs as a field. 
  A new cache is created for each new instance of IRIResolverNormal, and 
all calls into IRIResolverNormal are either via IRIResolver.create or 
globalResolver in IRIResolver.

So either IRIResolverNormal is used by a parser (new instance) or it's
used by a synchronized static. There is no need to use a concurent hash
map for resolvedIRIs.

If this is not the case, please could you provide point to the code
where it is not so.

	Andy

>
> thanks
>
> Simon

Mime
View raw message