Reputation: 29
I have a program which it explore file system, starting from a given root.The program recursively explores all directories from root point and performs a process on tiff files. indeed it merges each two tiff file. I used ExecutorService and ThreadPoolExecutor to handling merge function.
ExecutorService exec = Executors.newFixedThreadPool(threadsNumber);
inputDirectoryProcess( inputDir );
exec.shutdown();
try {
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
Also for every merge function I use following:
exec.submit(new MultipageTask( a, Integer.toString( intDetector(directoryFiles.get(i + 1).getName())/2 ), out) );
following is the MultipageTask class:
public void run() {
Thread thread = Thread.currentThread();
System.out.println("start by " + thread.getName() + " (" + thread.getId() + ")");
Integer[] resoulutions = null;
try {
BufferedImage image[] = new BufferedImage[tifImages.length];
for (int i = 0; i < tifImages.length; i++) {
resoulutions = getsize(tifImages[i].getPath());
SeekableStream ss = null;
ss = new FileSeekableStream(tifImages[i]);
ImageDecoder decoder = ImageCodec.createImageDecoder("tiff", ss, null);
PlanarImage op = null;
op = new NullOpImage(decoder.decodeAsRenderedImage(0),
null, OpImage.OP_IO_BOUND, null);
image[i] = op.getAsBufferedImage();
}
TIFFField[] fields = new TIFFField[3];
// ResolutionUnit
TIFFField fieldResUnit = new TIFFField(296, TIFFField.TIFF_SHORT, 1,
(Object) new char[] { 2 });
fields[0] = fieldResUnit;
// XResolution
TIFFField fieldXRes = new TIFFField(282, TIFFField.TIFF_RATIONAL, 1,
(Object) new long[][] { { resoulutions[0], 1 } });
fields[1] = fieldXRes;
// YResolution
TIFFField fieldYRes = new TIFFField(283, TIFFField.TIFF_RATIONAL, 1,
(Object) new long[][] { { resoulutions[1], 1 } });
fields[2] = fieldYRes;
TIFFEncodeParam params = new TIFFEncodeParam();
params.setCompression( TIFFEncodeParam.COMPRESSION_GROUP4 );
params.setExtraFields( fields );
OutputStream out = new FileOutputStream(outDir + "\\" + image_name + ".tif");
ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, params);
Vector vector = new Vector();
for (int i = 1; i < tifImages.length; i++) {
vector.add(image[i]);
}
params.setExtraImages(vector.iterator());
encoder.encode(image[0]);
out.close();
System.out.println("end by " + thread.getName() + " (" + thread.getId() + ")");
} catch (IOException e) {
e.printStackTrace();
}
increasetCount();
}
}
public synchronized void increasetCount() {
convertCount = convertCount + 2;
updateBar( convertCount );
}
after termination of the program, I noticed that some files haven't processed. So I logged enter and exit of threads as shown above. In console I see following lines:
start by pool-2-thread-4 (30)
end by pool-2-thread-2 (28)
start by pool-2-thread-2 (28)
start by pool-2-thread-4 (30)
start by pool-2-thread-2 (28)
start by pool-2-thread-1 (27)
start by pool-2-thread-1 (27)
start by pool-2-thread-4 (30)
end by pool-2-thread-1 (27)
end by pool-2-thread-2 (28)
start by pool-2-thread-1 (27)
start by pool-2-thread-2 (28)
As you see some threads like 28 starts, but don't finish. this cause loosing some merge process and program can't process all tiff files.
Note: I should mention that when I increase threadsNumber, the missing increases!!
How can I fix it? I want to sure that each thread finishes run process.
thanks and sorry for bad English.
Upvotes: 0
Views: 1278
Reputation: 8652
if you dont have shared resources and its not a deadlock/livelock, try to surround your code with try/catch
public class MultipageTask implements Runnable {
private File[] tifImages;
private String image_name;
private String outDir;
public MultipageTask(File[] tifImages, String image_name, String outDir) {
this.tifImages = tifImages;
this.image_name = image_name;
this.outDir = outDir;
}
@Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println("start by " + thread.getName() + " (" + thread.getId() + ")");
try{
// doing merge process
}catch(Exception e){
e.printStackTrace();
}
System.out.println("end by " + thread.getName() + " (" + thread.getId() + ")");
}
}
Upvotes: 2