I written a listener which listen to queue continuously, as message arrive it should write that message to file.
@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);
}
line in above method
ResponseWriter.responseWrite(response, correlationId);
will call below method:
File file =new File(defaultExcelPath);
FileOutputStream fop = null;
PrintWriter writer = null;
synchronized(file) {
try {
List datalist = new ArrayList();
// 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();
}
}
but due to handler method listing more than 100 messages in some seconds, file writing method throws below exception
java.io.FileNotFoundException: C:\Files\performanceEvaluator.csv (The process cannot access the file because it is being used by another process)
how I can make the code which write to the file concurrently (or any other way..)
解决方案
This is where the keyword synchronized comes into play. Declaring a function in this: public synchronized void function() manner does two things:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.