提交 960e88f0 编写于 作者: C chegar

8010282: sun.net.www.protocol.jar.JarFileFactory.close(JarFile) should be thread-safe

Reviewed-by: khazra, alanb
上级 62bd6c60
...@@ -51,7 +51,7 @@ public class JarURLConnection extends java.net.JarURLConnection { ...@@ -51,7 +51,7 @@ public class JarURLConnection extends java.net.JarURLConnection {
/* the Jar file factory. It handles both retrieval and caching. /* the Jar file factory. It handles both retrieval and caching.
*/ */
private static JarFileFactory factory = new JarFileFactory(); private static final JarFileFactory factory = JarFileFactory.getInstance();
/* the url for the Jar file */ /* the url for the Jar file */
private URL jarFileURL; private URL jarFileURL;
......
...@@ -43,13 +43,24 @@ import sun.net.util.URLUtil; ...@@ -43,13 +43,24 @@ import sun.net.util.URLUtil;
class JarFileFactory implements URLJarFile.URLJarFileCloseController { class JarFileFactory implements URLJarFile.URLJarFileCloseController {
/* the url to file cache */ /* the url to file cache */
private static HashMap<String, JarFile> fileCache = new HashMap<String, JarFile>(); private static final HashMap<String, JarFile> fileCache = new HashMap<>();
/* the file to url cache */ /* the file to url cache */
private static HashMap<JarFile, URL> urlCache = new HashMap<JarFile, URL>(); private static final HashMap<JarFile, URL> urlCache = new HashMap<>();
private static final JarFileFactory instance = new JarFileFactory();
private JarFileFactory() { }
public static JarFileFactory getInstance() {
return instance;
}
URLConnection getConnection(JarFile jarFile) throws IOException { URLConnection getConnection(JarFile jarFile) throws IOException {
URL u = urlCache.get(jarFile); URL u;
synchronized (instance) {
u = urlCache.get(jarFile);
}
if (u != null) if (u != null)
return u.openConnection(); return u.openConnection();
...@@ -62,16 +73,16 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { ...@@ -62,16 +73,16 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController {
JarFile get(URL url, boolean useCaches) throws IOException { JarFile get(URL url, boolean useCaches) throws IOException {
JarFile result = null; JarFile result;
JarFile local_result = null; JarFile local_result;
if (useCaches) { if (useCaches) {
synchronized (this) { synchronized (instance) {
result = getCachedJarFile(url); result = getCachedJarFile(url);
} }
if (result == null) { if (result == null) {
local_result = URLJarFile.getJarFile(url, this); local_result = URLJarFile.getJarFile(url, this);
synchronized (this) { synchronized (instance) {
result = getCachedJarFile(url); result = getCachedJarFile(url);
if (result == null) { if (result == null) {
fileCache.put(URLUtil.urlNoFragString(url), local_result); fileCache.put(URLUtil.urlNoFragString(url), local_result);
...@@ -99,14 +110,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { ...@@ -99,14 +110,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController {
* remove the JarFile from the cache * remove the JarFile from the cache
*/ */
public void close(JarFile jarFile) { public void close(JarFile jarFile) {
synchronized (instance) {
URL urlRemoved = urlCache.remove(jarFile); URL urlRemoved = urlCache.remove(jarFile);
if( urlRemoved != null) { if (urlRemoved != null)
fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); fileCache.remove(URLUtil.urlNoFragString(urlRemoved));
} }
} }
private JarFile getCachedJarFile(URL url) { private JarFile getCachedJarFile(URL url) {
assert Thread.holdsLock(instance);
JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); JarFile result = fileCache.get(URLUtil.urlNoFragString(url));
/* if the JAR file is cached, the permission will always be there */ /* if the JAR file is cached, the permission will always be there */
......
...@@ -43,13 +43,24 @@ import sun.net.util.URLUtil; ...@@ -43,13 +43,24 @@ import sun.net.util.URLUtil;
class JarFileFactory implements URLJarFile.URLJarFileCloseController { class JarFileFactory implements URLJarFile.URLJarFileCloseController {
/* the url to file cache */ /* the url to file cache */
private static HashMap<String, JarFile> fileCache = new HashMap<String, JarFile>(); private static final HashMap<String, JarFile> fileCache = new HashMap<>();
/* the file to url cache */ /* the file to url cache */
private static HashMap<JarFile, URL> urlCache = new HashMap<JarFile, URL>(); private static final HashMap<JarFile, URL> urlCache = new HashMap<>();
private static final JarFileFactory instance = new JarFileFactory();
private JarFileFactory() { }
public static JarFileFactory getInstance() {
return instance;
}
URLConnection getConnection(JarFile jarFile) throws IOException { URLConnection getConnection(JarFile jarFile) throws IOException {
URL u = urlCache.get(jarFile); URL u;
synchronized (instance) {
u = urlCache.get(jarFile);
}
if (u != null) if (u != null)
return u.openConnection(); return u.openConnection();
...@@ -72,16 +83,16 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { ...@@ -72,16 +83,16 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController {
} }
} }
JarFile result = null; JarFile result;
JarFile local_result = null; JarFile local_result;
if (useCaches) { if (useCaches) {
synchronized (this) { synchronized (instance) {
result = getCachedJarFile(url); result = getCachedJarFile(url);
} }
if (result == null) { if (result == null) {
local_result = URLJarFile.getJarFile(url, this); local_result = URLJarFile.getJarFile(url, this);
synchronized (this) { synchronized (instance) {
result = getCachedJarFile(url); result = getCachedJarFile(url);
if (result == null) { if (result == null) {
fileCache.put(URLUtil.urlNoFragString(url), local_result); fileCache.put(URLUtil.urlNoFragString(url), local_result);
...@@ -109,13 +120,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { ...@@ -109,13 +120,15 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController {
* remove the JarFile from the cache * remove the JarFile from the cache
*/ */
public void close(JarFile jarFile) { public void close(JarFile jarFile) {
synchronized (instance) {
URL urlRemoved = urlCache.remove(jarFile); URL urlRemoved = urlCache.remove(jarFile);
if( urlRemoved != null) { if (urlRemoved != null)
fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); fileCache.remove(URLUtil.urlNoFragString(urlRemoved));
} }
} }
private JarFile getCachedJarFile(URL url) { private JarFile getCachedJarFile(URL url) {
assert Thread.holdsLock(instance);
JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); JarFile result = fileCache.get(URLUtil.urlNoFragString(url));
/* if the JAR file is cached, the permission will always be there */ /* if the JAR file is cached, the permission will always be there */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册