java.io.FileNotFoundException:进程无法访问该文件,因为它正由另一个进程使用)

时间:2015-03-24 11:21:03

标签: java multithreading concurrency

我写了一个连续监听队列的监听器,因为消息到达它应该将该消息写入文件。

@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.FileNotFoundException:C:\ Files \ performanceEvaluator.csv(进程无法访问该文件,因为它正由另一个进程使用)

我如何能够同时(或任何其他方式...)

创建写入文件的代码

2 个答案:

答案 0 :(得分:1)

另一种方法是只需在熟悉的锁定你自己的类时进行同步。或者,您可以声明一个类型为object的静态变量并锁定它。

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

答案 1 :(得分:-1)

这是关键字synchronized发挥作用的地方。以这种:public synchronized void function()方式声明一个函数可以做两件事:

  
      
  1. 首先,对同一对象的两个同步方法的调用不可能进行交错。当一个线程正在为一个对象执行一个synchronized方法时,所有其他线程都会调用同一个对象的同步方法(暂停执行),直到第一个线程完成该对象为止。
  2.   
  3. 其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立一个先发生关系。这可以保证对所有线程都可以看到对象状态的更改。
  4.   

来自Java Tutorials