RFR: 8060130: Simplify the synchronization of defining and getting java.lang.Package
Peter Levart
peter.levart at gmail.com
Mon Oct 13 15:05:45 UTC 2014
Hi Claes,
Regarding CachedManifest I have one more comment. It's usually better to
use null/zero as "uninitialized" state for lazy-initialized fields. You
spare one (volatile) write and don't worry about unsafe publication
which might see the Java-default value instead of the one assigned in
initializer as "uninitialized". So summing-up all comments from previous
mails I would write CachedManifest class as:
private static class CachedManifest {
static final Manifest NO_MANIFEST = new Manifest();
final String fileName;
private final URL url;
private volatile Manifest manifest;
CachedManifest(final String fileName) {
this.fileName = fileName;
this.url = AccessController.doPrivileged(new
PrivilegedAction<URL>() {
public URL run() {
final File file = new File(fileName);
if (file.isFile()) {
try {
return ParseUtil.fileToEncodedURL(file);
} catch (MalformedURLException e) {
}
}
return null;
}
});
}
public URL getURL() {
return url;
}
public Manifest getManifest() {
if (url == null) return null;
Manifest m = manifest;
if (m == null) {
synchronized (this) {
if ((m = manifest) == null) {
manifest = m =
AccessController.doPrivileged(new PrivilegedAction<Manifest>() {
public Manifest run() {
try (FileInputStream fis = new
FileInputStream(fileName);
JarInputStream jis = new
JarInputStream(fis, false))
{
return jis.getManifest();
} catch (IOException e) {
return NO_MANIFEST;
}
}
});
}
}
}
return (m == NO_MANIFEST) ? null : m;
}
}
What do you say?
Regards, Peter
On 10/13/2014 04:32 PM, Peter Levart wrote:
> On 10/12/2014 04:09 AM, Claes Redestad wrote:
>>
>>
>> http://cr.openjdk.java.net/~redestad/8060130/webrev.03/
>>
>
> Hi Claes,
>
> First, one more nit:
>
> 1635 if (!map.containsKey(pkgName)) {
> 1636 map.put(pkgName, pkg);
> 1637 }
>
> ..could be written as:
>
> map.putIfAbsent(pkgName, pkg);
>
>
>
> And second, I re-read the code of CachedManifest and noticed the
> following. You initialize the volatile instance field 'manifest' like
> that:
>
> 609 private volatile Manifest manifest = EMPTY_MANIFEST;
>
>
> So in following code:
>
> 631 public Manifest getManifest() {
> 632 resolveManifest();
> 633 return manifest;
> 634 }
> 635
> 636 private void resolveManifest() {
> 637 if (manifest != null || url == null) {
> 638 return;
> 639 }
> 640 synchronized(this) {
> 641 if (manifest == null) {
> 642 manifest = AccessController.doPrivileged(new
> PrivilegedAction<Manifest>() {
> 643 public Manifest run() {
> 644 return loadManifest(fileName);
> 645 }
> 646 });
> 647 }
> 648 }
> 649 }
>
>
>
> ... loadManifest() will never be executed. getManifest() will always
> return EMPTY_MANIFEST.
>
> You probably wanted line 637 to be written as:
>
> if (manivest != EMPTY_MANIFEST || url == null) { ...
>
>
> Likewise in loadManifest(), wou write:
>
> 586 private static Manifest loadManifest(String fn) {
> 587 try (FileInputStream fis = new FileInputStream(fn);
> 588 JarInputStream jis = new JarInputStream(fis, false))
> 589 {
> 590 return jis.getManifest();
> 591 } catch (IOException e) {
> 592 return EMPTY_MANIFEST;
> 593 }
> 594 }
>
> ..but you probably wanted the line 592 to return 'null' instead.
>
>
> Regards, Peter
>
More information about the core-libs-dev
mailing list