Make 1 Thread wait for an array of Threads to complete

I have an array of threads called workers. There is another separate thread called status.

Both threads access a shared LinkedBlockingQueue. Workers(thread array) uses poll() to pull work and status reports the size of the queue every 30 seconds.

My problem in running this is I get the following printed from the status class:

UPLOADING...

PREVIEWING...

But PREVIEWING should appear before, and only before, UPLOADING. So, I think my status object is not waiting for the first batch of workers to complete?

I want this:

DOWNLOADING....

PREVIEWING....

UPLOADING...

but instead things are a bit out of sync.

// start up the Status Object class.
        int downloadSize = filesToDownload.size();
        Thread statusThread = new Thread(new Status(filesToDownload, currentYear, downloadSize, "DOWNLOADING..."));
        statusThread.start();

        /**
         * download the files
         */

        Thread[] workers = new Thread[NUMBER_OF_THREADS];
        for (int x = 0; x < NUMBER_OF_THREADS; x++) {
            workers[x] = new Thread(new S3ObjectDownloader(filesToDownload, currentYear));
            workers[x].start();
        }
        for (int x = 0; x < NUMBER_OF_THREADS; x++) {
            try {
                workers[x].join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /**
         * create previews
         */
        int previewSize = filesToPreview.size();
        statusThread = new Thread(new Status(filesToPreview, currentYear, previewSize, "PREVIEWING..."));
        statusThread.start();

        workers = new Thread[NUMBER_OF_THREADS];
        for (int x = 0; x < NUMBER_OF_THREADS; x++) {
            workers[x] = new Thread(new Worker(filesToPreview, currentYear));
            workers[x].start();
        }
        for (int x = 0; x < NUMBER_OF_THREADS; x++) {
            try {
                workers[x].join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /**
         * upload previews to S3.
         */
        // we need the TransferManager for the uploads.
        TransferManager txManager = new TransferManager(new ClasspathPropertiesFileCredentialsProvider());
        statusThread = new Thread(new Status(filesToUpload, currentYear, filesToUpload.size(), "UPLOADING..."));
        statusThread.start();

        workers = new Thread[NUMBER_OF_THREADS];
        for (int x = 0; x < NUMBER_OF_THREADS; x++) {
            workers[x] = new Thread(new S3ObjectUploader(filesToUpload, currentYear, txManager));
            workers[x].start();
        }
        for (int x = 0; x < NUMBER_OF_THREADS; x++) {
            try {
                workers[x].join();
            } catch (InterruptedException e) { 
                // TODO Auto-generated catch
                // block
                e.printStackTrace();
            }
        }

        // shutdown transfer manager
        txManager.shutdownNow();

Here is Status.java

public class Status implements Runnable {

    private String conferenceYear;
    private Queue<String>queue;
    private int queueSize;
    private String jobeName;

    public Status(Queue<String> queue, String conferenceYear, int queueSize, String jobName){
        this.conferenceYear = conferenceYear;
        this.queue = queue;
        this.queueSize = queueSize;
        this.jobeName = jobName;
    }

    @Override
    public void run() {
        while(!queue.isEmpty()){
            try {
                float completion = (queue.size() * 1.0f) / this.queueSize;
                System.out.println(this.jobeName+" : "+this.conferenceYear+ " remaining..."+MessageFormat.format("{0,number,#.##%}",completion));
                TimeUnit.SECONDS.sleep(30);;
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

}

Answers


Java has CountDownlatches to support such scenarios.

Take a look at CountDownLatch class.

The link also contains a sample implementation which is very easy to understand. You can create latches to signal start and wait for end for each of your task.


Need Your Help

Unable to move User Control registration into nested web.config

c# asp.net visual-studio-2010 web-config

Okay, I've been banging my head against this for almost five hours now, so I figure it's time to ask.

How to define a Label class in MyEclipse?

java database swing label resultset

I have set many lables and I want them to show the data from database.But it shows"com.myql.jdbc.JDBC4ResultSet"