2015-03-24 1 views
0

Я написал прослушиватель, который постоянно слушает очередь, по мере поступления сообщения он должен записать это сообщение в файл.java.io.FileNotFoundException: процесс не может получить доступ к файлу, потому что он используется другим процессом)

@Override 
public void handleDelivery(String consumerTag, 
          Envelope envelope, 
          AMQP.BasicProperties properties, 
          byte[] body) throws IOException { 
    String response = new String(body); 

    String routingKey = envelope.getRoutingKey(); 
    String contentType = properties.getContentType(); 
    String correlationId = properties.getCorrelationId(); 
    System.out.println("response "+ counter+ " :: "+ response); 
     try { 
      ResponseWriter.responseWrite(response, correlationId); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    Runnable task = new VariableLengthTask(this, envelope.getDeliveryTag(), channel, 1000); 
    executorService.submit(task); 

} 

линия выше метода

ResponseWriter.responseWrite(response, correlationId); 

позвонит ниже способом:

File file =new File(defaultExcelPath); 
     FileOutputStream fop = null; 
     PrintWriter writer = null; 
     synchronized(file) { 
      try { 
       List<String> datalist = new ArrayList<String>(); 
       // add details to datalist.... 
       // write to the file .. 
       ..... 
       ..... 
       ..... 

       fop = new FileOutputStream(defaultExcelPath, true); 
       writer = new PrintWriter(fop); 
       for(String data : datalist) { 
        writer.println(data); 
       } 
       writer.close(); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       //e.printStackTrace(); 
       throw e; 
      } finally { 
       if(fop!= null) fop.close(); 
       if(writer!= null) writer.close(); 
      } 
     } 

, но из-за метода обработчика листинга более 100 сообщений в несколько секунд, метод записи файла броски ниже исключения

java.io.FileNotFo undException: C: \ Files \ performanceEvaluator.csv (Процесс не может получить доступ к файлу, так как он используется другим процессом)

как я могу сделать код, который запись в файл одновременно (или любым другим способом. .)

+3

вы не синхронизируются на том же файле, каждый вызов метода создать новый файловый объект и устанавливает блокировку на этот новый объект, поэтому он не синхронизируются, попробуйте синхронизации на 'responseWrite', поскольку его статический метод просто сделать его синхронизировано –

ответ

-1

Это ключевое слово . Объявление функции в этом: public synchronized void function() образом делает две вещи:

  1. Во-первых, это не возможно для двух вызовов синхронизированных методов на том же объекте чередовать. Когда один поток выполняет синхронизированный метод для объекта, все другие потоки, которые вызывают синхронизированные методы для одного и того же блока объектов (приостанавливают выполнение) до тех пор, пока первый поток не будет выполнен с объектом.
  2. Во-вторых, когда синхронизированный метод завершается, он автоматически устанавливает связь между событиями и последующим вызовом синхронизированного метода для одного и того же объекта. Это гарантирует, что изменения состояния объекта будут видны для всех потоков.

Из Java Tutorials.

+2

"менее известный"? Кроме того, на самом деле это не ответ, а всего лишь копия папок Java Docs. –

+0

@ FluffmeisterGeneral да ** «менее известен» **, потому что большинство людей не знают об этом. – nom

+1

Это очень часто используемое ключевое слово –

1

Другой способ - просто синхронизировать, когда это необходимо, с известным замком вашего собственного класса. В качестве альтернативы вы можете объявить статическую переменную типа объекта и заблокировать ее.

class MyClass{ 

    File file =new File(defaultExcelPath); 
    FileOutputStream fop = null; 
    PrintWriter writer = null; 
    { 
     try {//better to move this to its own fn. one fn one thing and probably dont need to sync this 
      List<String> datalist = new ArrayList<String>(); 
      // add details to datalist.... 
      // write to the file .. 
      ..... 
      ..... 
      ..... 
      }catch ...//compelte earlier try 

     synchronized(MyClass.class) { 
     try{ 

      // fop = ; 
      writer = new PrintWriter(new FileOutputStream(defaultExcelPath, true)); 
      for(String data : datalist) { 
       writer.println(data); 
      } 
      // writer.close();//dont close here 
     } catch (Exception e) { 
      //no point throwing error what will the calling code do? 
      //jjust log it 
      logger.warn(e,e);//if you dont have logging framework get it or make system.out 
     } finally { 
      if(writer!= null) try{ 
      writer.close(); 
      }catch 
      //complete 
      // if(fop!= null) writer.close(); 
      //in this case dont need to open two objects, just wrap it in 
      //but if u do have 2 object add seperate try-catch to close each inside the final 
     } 
    } 
    } 
    // not tested code please close braces etc 
+0

Разве это не намного больше, чем добавление 'synchronized' к методу? – nom

+0

Нет, отдельный try catch все равно будет нужен, если его метод. и действительно сборник Список datalist = new ArrayList (); // добавьте подробности в datalist .... // напишите в файл .. ..... должен быть на другом методе. – tgkprog

Смежные вопросы

 Смежные вопросы