2011-12-22 30 views
29

Si alguna vez ha usado un software de descarga p2p, pueden descargar un archivo con multi-threading, y crearon solo un archivo, entonces me pregunto cómo los hilos escriben datos en ese archivo. ¿Secuencialmente o en paralelo?¿Pueden varios hilos escribir datos en un archivo al mismo tiempo?

Imagine que desea volcar una gran tabla de base de datos en un archivo, y cómo hacer que este trabajo sea más rápido?

+13

Sí, pueden hacerlo, pero realmente quiere evitar que lo hagan exactamente al mismo tiempo. Es necesario que haya algo de coordinación. Si está hablando de Bittorrent, creo que funciona ensamblando bloques de compensaciones conocidas en un archivo de tamaño conocido. Eso no se puede llamar de forma secuencial o paralela, es más de "acceso aleatorio". – Thilo

+0

Pregunta similar: http://stackoverflow.com/questions/6206472/what-is-the-best-way-to-write-to-a-file-in-a-parallel-thread-in-java – Vadzim

Respuesta

21

Puede usar varios hilos para escribir en un archivo, p. un archivo de registro. pero debes coordinar tus hilos como señala @Thilo. O necesita sincronizar el acceso a archivos y solo escribir registros/líneas completos, o necesita tener una estrategia para asignar regiones del archivo a diferentes hilos, p. reconstruir un archivo con compensaciones y tamaños conocidos.

Esto rara vez se hace por razones de rendimiento, ya que la mayoría de los subsistemas de discos funcionan mejor cuando se escriben secuencialmente y el disco IO es el cuello de botella. Si la CPU para crear el registro o la línea de texto (o IO de red) es el cuello de botella, puede ser útil.

Imagen que desea volcar una gran tabla de base de datos a un archivo, y cómo hacer este trabajo más rápido?

Escribirlo secuencialmente es probable que sea el más rápido.

+0

Use a semáforo –

0

Puede hacer que varios hilos escriban en el mismo archivo, pero de a uno por vez. Todos los hilos necesitarán ingresar a un bloque sincronizado antes de escribir en el archivo.

En el ejemplo P2P, una forma de implementarlo es encontrar el tamaño del archivo y crear un archivo vacío de ese tamaño. Cada hilo está descargando diferentes secciones del archivo: cuando necesitan escribir, entrarán en un bloque sincronizado, mueven el puntero del archivo usando buscar y escribir el contenido del buffer.

+0

"Todos los hilos necesitarán ingresar a un bloque sincronizado antes de escribir en el archivo". Bueno, no tienen * que. Pero entonces no te gustará la salida, que podría ser intercalada de manera divertida. – Thilo

1

¿Qué tipo de archivo es este? ¿Por qué necesitas alimentarlo con más hilos? Depende de las características (no sé mejor palabra para ello) del uso del archivo.

La transferencia de un archivo desde varios lugares en la red (abreviado: Torrent-like)

Si va a transferir un archivo existente, el programa debe

  • tan pronto, como se pone conocer la tamaño del archivo, créelo con contenido vacío: esto evita un error posterior fuera del disco (si no hay espacio suficiente, se activará en la creación, antes de descargarlo), también ayuda al rendimiento;
  • si organiza bien la transferencia (y por qué no), cada subproceso será responsable de una parte distinta del archivo, por lo que las escrituras serán distintas,
  • aunque de alguna manera dos subprocesos elijan la misma parte del archivo, no causará ningún error, ya que escriben los mismos datos para las mismas posiciones de archivo.

Al añadir bloques de datos a un archivo (abreviado: tala)

Si los hilos simplemente añade información fija o varia-longitud en un archivo, se debe utilizar un hilo común. Debe usar un buffer de escritura relativamente grande, para que pueda servir a los hilos del cliente de manera rápida (solo tomando las cuerdas), y eliminarlo de la programación óptima y del tamaño del bloque. Debe usar un disco dedicado o incluso una computadora.

Además, puede haber varios problemas de rendimiento, es por eso que hay servidores de registro alrededor, incluso los comerciales caros.

de lectura y escritura de tiempo aleatorio, posición aleatoria (abreviado: base de datos)

Se requiere un diseño complejo, con mutex etc., nunca he hecho esto un poco, pero puedo imaginar. Pídale algunos trucos a Oracle :)

2

La declaración sincronizada permite hacer esto. Pruebe el siguiente código que utilizo en un contexto similar.

package hrblib; 

import java.io.*; 

public class FileOp { 

    static int nStatsCount = 0; 

    static public String getContents(String sFileName) { 

     try { 
      BufferedReader oReader = new BufferedReader(new FileReader(sFileName)); 
      String sLine, sContent = ""; 
      while ((sLine=oReader.readLine()) != null) { 
       sContent += (sContent=="")?sLine: ("\r\n"+sLine); 
      } 
      oReader.close(); 
      return sContent; 
     } 
     catch (IOException oException) { 
      throw new IllegalArgumentException("Invalid file path/File cannot be read: \n" + sFileName); 
     } 
    } 
    static public void setContents(String sFileName, String sContent) { 
     try { 
      File oFile = new File(sFileName); 
      if (!oFile.exists()) { 
       oFile.createNewFile(); 
      } 
      if (oFile.canWrite()) { 
       BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName)); 
       oWriter.write (sContent); 
       oWriter.close(); 
      } 
     } 
     catch (IOException oException) { 
      throw new IllegalArgumentException("Invalid folder path/File cannot be written: \n" + sFileName); 
     } 
    } 
    public static synchronized void appendContents(String sFileName, String sContent) { 
     try { 

      File oFile = new File(sFileName); 
      if (!oFile.exists()) { 
       oFile.createNewFile(); 
      } 
      if (oFile.canWrite()) { 
       BufferedWriter oWriter = new BufferedWriter(new FileWriter(sFileName, true)); 
       oWriter.write (sContent); 
       oWriter.close(); 
      } 

     } 
     catch (IOException oException) { 
      throw new IllegalArgumentException("Error appending/File cannot be written: \n" + sFileName); 
     } 
    } 
} 
Cuestiones relacionadas