Kia_s
Kia_s

Reputation: 29

java: threads doesn't finish run() method completely?

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

Answers (1)

Dima
Dima

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

Related Questions