variable threads synchronizable sincronizar productor procesos example ejemplo consumidor java multithreading concurrency synchronization

threads - Métodos sincronizados en Java IO Streams



synchronized java ejemplo (3)

Esto se debe a la razón, que mark () y reset () funcionan juntos como se puede ver en la documentación.

marca nula pública (int readlimit): marca la posición actual en este flujo de entrada. Una llamada posterior al método de reset vuelve a colocar esta secuencia en la última posición marcada para que las lecturas posteriores vuelvan a leer los mismos bytes.

Si tiene varios subprocesos que comparten el mismo InputStream, podría dar lugar a problemas, si estos dos métodos no se sincronizaran.

Actualizar a comentar

java.io.InputStream es una clase abstracta, por lo que creo que la sincronización es más para las clases que heredan InputStream como una sugerencia. Los métodos mark() y reset() solo se utilizarán, si markSupported() devuelve true. Y en la clase java.io.InputStream#markSupported() devuelve falso.

/** * Tests if this input stream supports the <code>mark</code> and * <code>reset</code> methods. Whether or not <code>mark</code> and * <code>reset</code> are supported is an invariant property of a * particular input stream instance. The <code>markSupported</code> method * of <code>InputStream</code> returns <code>false</code>. * * @return <code>true</code> if this stream instance supports the mark * and reset methods; <code>false</code> otherwise. * @see java.io.InputStream#mark(int) * @see java.io.InputStream#reset() */ public boolean markSupported() { return false; }

En Java desde Java 1.0 en la clase java.io.InputStream hay métodos

public synchronized void mark(int readlimit) {}

y

public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); }

¿Por qué esos dos métodos están sincronizados mientras que los otros no están sincronizados?


Hay algunos hechos contradictorios que señalan que la palabra clave sincronizada es solo un error aquí:

  1. Seguro que es solo una pista para los desarrolladores. Los métodos están vacíos y synchronized palabra clave synchronized no se hereda en las subclases.

  2. Por otro lado, otros métodos no están sincronizados, incluso los métodos abstractos y vacíos. Eso significa que se nos advirtió que no olvidáramos la sincronización en la marca / reinicio, pero no se nos advirtió sobre las llamadas de read() concurrentes. Eso no tiene sentido porque la lectura concurrente no funcionará sin la sincronización.

  3. Muchas de las implementaciones de secuencias JDK tienen un uso incoherente de palabras clave sincronizadas.

  4. java.io.InputStream se coloca frente a java.nio.Buffer casi no tiene implementaciones de métodos básicos útiles, pero se convirtió en una clase. Por lo tanto, trata de mantener el equilibrio entre este ''suministro de esqueleto'' y la declaración de contratos de métodos generales.


Ya que los métodos mark () y reset () no tienen código dentro de ellos, la palabra "sincronizado" es solo un "recordatorio" para implementar clases en las que deben poner bloqueos o en estos métodos cuando los anulan. Esto es para prevenir condiciones de carrera en casos de uso de múltiples hilos.

Ahora, otros métodos de InputStream no están marcados como "sincronizados" porque estos métodos nunca emitirán una excepción IndexOutOfBoundsException, BufferOverflowException, etc. (A menos que pase en malos tampones). Estos métodos siempre devuelven un -1 cuando no hay más bytes para leer en lugar de lanzar una excepción. Así que no necesitan estar sincronizados.

Notarás que read () es abstracto. Y las clases de implementación sí especifican "sincronizadas" cuando implementan este método.

En otras palabras, la clase abstracta de InputStream puede manejar múltiples subprocesos y las clases de implementación también deberían.