El JDK URLDecoder no fue implementado de manera eficiente. En particular, internamente se basa en StringBuffer (que introduce innecesariamente la sincronización en el caso de URLDecoder). Apache commons proporciona URLCodec, pero también se ha informado que tiene problemas similares en cuanto al rendimiento, pero no he verificado que siga siendo así en la versión más reciente.
Mark A. Ziesemer escribió una publicación hace un tiempo sobre los problemas y el rendimiento con URLDecoder. Logró algunos informes de errores y terminó escribiendo un reemplazo completo. Debido a que esto es así, voy a citar algunos extractos clave aquí, pero que realmente debería leer el artículo original aquí: http://blogger.ziesemer.com/2009/05/improving-url-coder-performance-java.html
cotizaciones seleccionados:
Java proporciona una implementación por defecto de esta funcionalidad en java .net.URLEncoder y java.net.URLDecoder. Lamentablemente, no es el mejor rendimiento, tanto por la forma en que se escribió la API como por los detalles de dentro de la implementación. Se han presentado una serie de errores relacionados con el rendimiento en sun.com en relación con URLEncoder.
Existe una alternativa: org.apache.commons.codec.net.URLCodec de Apache Commons Codec. (Commons Codec también proporciona una implementación útil para la codificación Base64.) Desafortunadamente, Commons 'URLCodec sufre algunos de los mismos problemas que URLEncoder/URLDecoder de Java.
...
Recomendaciones para ambos el JDK y los Comunes:
Cuando la construcción de cualquiera de las clases "amortiguador", por ejemplo, ByteArrayOutputStream, CharArrayWriter, StringBuilder o StringBuffer, calcule y otorgue una capacidad estimada. El URLEncoder del JDK actualmente hace esto para su StringBuffer, pero debería hacer esto para su instancia CharArrayWriter también. El URLCodec de Common debería hacer esto para su instancia ByteArrayOutputStream. Si los tamaños predeterminados del buffer de las clases son demasiado pequeños, pueden tener que cambiar el tamaño copiando en nuevos buffers más grandes, lo cual no es exactamente una operación "barata". Si los tamaños de búfer predeterminados de las clases son demasiado grandes, la memoria puede ser innecesariamente desperdiciada.
Ambas implementaciones dependen de Charsets, pero solo las aceptan como su nombre de cadena. Charset proporciona un caché simple y pequeño para las búsquedas de nombre , que almacena solo los últimos 2 Charsets utilizados. Esto no se debe confiar en , y ambos deben aceptar instancias Charset para otras razones de interoperabilidad también.
Ambas implementaciones solo manejan entradas y salidas de tamaño fijo. El El URLEncoder de JDK solo funciona con instancias String. Commons 'URLCodec también se basa en cadenas, pero también funciona con matrices byte []. Esta es una restricción de nivel de diseño que esencialmente impide el procesamiento eficiente de entradas más grandes o de longitud variable. En su lugar, se deben admitir las interfaces " " de soporte de flujo tales como CharSequence, Appendable y las implementaciones Buffer de Buffer de ByteBuffer y CharBuffer de java.nio.
...
Tenga en cuenta que com.ziesemer.utils.urlCodec es más de 3 veces más rápido que el JDK URLEncoder, y más de 1,5 veces más rápido que el JDK URLDecoder. (Del JDK URLDecoder era más rápido que el URLEncoder, así que no había tanta margen de mejora.)
Creo que su colega es erróneo sugerir URLDecode no es seguro para subprocesos. Otras respuestas aquí explican en detalle.
EDITAR [2012-07-03] - Por más adelante comentario Publicado por OP
No
seguro de si estaban buscando más ideas o no? Tiene razón en que si tiene la intención de operar en la lista como una colección atómica, deberá sincronizar todo el acceso a la lista, incluidas las referencias fuera de su método. Sin embargo, si está de acuerdo con los contenidos de la lista devuelta que difieren potencialmente de la lista original, un enfoque de fuerza bruta para operar en un "lote" de cadenas de una colección que podría ser modificado por otros hilos podría ser similar a esto:
/**
* @param origList will be copied by this method so that origList can continue
* to be read/write by other threads.
* @return list containing decoded strings for each entry that was
in origList at time of copy.
*/
public List<String> decodeListOfStringSafely(List<String> origList)
throws UnsupportedEncodingException {
List<String> snapshotList = new ArrayList<String>(origList);
List<String> newList = new ArrayList<String>();
for (String urlStr : snapshotList) {
String decodedUrlStr = URLDecoder.decode(urlStr, "UTF8");
newList.add(decodedUrlStr);
}
return newList;
}
Si eso no ayuda, entonces todavía no estoy seguro de lo que está buscando y sería mejor que lo haga para crear una nueva, más concisa, pregunta. Si eso es lo que preguntaba, tenga cuidado porque este ejemplo fuera de contexto no es una buena idea por muchas razones.
A menos que el método estático se base en variables estáticas en la clase URLDecoder, cada llamada al método va a la pila por separado y es segura para la ejecución de subprocesos. No veo ningún motivo por el que URLDecoder.decode (...) necesite ningún acceso a los recursos compartidos. – Thomas