简体   繁体   中英

Get Size of BlockingQueue while Multithreading

I have a multi-threaded process, 5 threads, and another thread working as a status object reporting the size of the BlockingQueue. Problem is the Status thread reports 100% first, which is correct, but then goes right to 0%.

I want it to count down the percentage.

Here is my code:

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();
            }
        }

Here is the status object instantiation:

int downloadSize = filesToDownload.size();
        Thread statusThread = new Thread(new Status(filesToDownload, currentYear,downloadSize,"DOWNLOADING..."));
        statusThread.start();

Here is that actual Status object run method:

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

}

Im adding in the actual S3ObjectDownloader:

public void run() {
        //aws credentials
        this.s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());

        //log4j configuration
        PropertyConfigurator.configure("/home/ubuntu/log4j.properties");

        //attempt to poll the queue
        while (!queue.isEmpty()) {

            String fileName = queue.poll() + ".mp4";
            String FULL_PATH = "best_of_ats/" + this.conferenceYear + "/videos/" + fileName;
            File f = new File("/home/ubuntu/" + fileName);

            if (fileName != null && !f.exists() && s3.doesObjectExist(BUCKET_NAME, FULL_PATH)) {
                OutputStream out = null;
                InputStream in = null;
                S3Object s3obj = null;


                    try {
                        s3obj = s3.getObject(this.BUCKET_NAME,
                                FULL_PATH);
                        in = s3obj.getObjectContent();
                        //System.out.println("Downloading File " + FULL_PATH + "....");
                    } catch (AmazonS3Exception s3e) {
                        // s3e.printStackTrace();
                        //System.out.println("Problem downloading file..." + FULL_PATH);
                        s3e.printStackTrace();
                        logger.info("Problem with file..." + FULL_PATH);
                        continue;
                    }

                    try {
                        out = new FileOutputStream(new File(fileName));
                        int read = 0;
                        byte[] bytes = new byte[1024];
                        while ((read = in.read(bytes)) != -1) {
                            out.write(bytes, 0, read);
                        }

                        out.flush();
                        out.close();
                        in.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        //System.out.println("problem writing output..." + FULL_PATH);
                        logger.info("problem writing output..." +FULL_PATH);
                        continue;
                    }



            }

        } // end while...
    }

And here is the Status Class:

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)/this.queueSize;
                System.out.println(this.jobeName+" : "+this.conferenceYear+ " completion..."+MessageFormat.format("{0,number,#.##%}",completion));
                TimeUnit.SECONDS.sleep(30);;
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

}

Here is the calling class:

public static void main(String[] args) {

        BlockingQueue<String> filesToDownload = new LinkedBlockingDeque<String>(1024);
        BlockingQueue<String> filesToPreview = new LinkedBlockingDeque<String>(1024);
        BlockingQueue<String> filesToUpload = new LinkedBlockingDeque<String>(1024);
        String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));

        // DB connection.
        ATSStoreDB db = new ATSStoreDB();
        PreparedStatement st = null;
        Connection conn = null;
        conn = db.getConnection();

        // get ids from ats_store.products.
        try {
            st = conn.prepareStatement(sql);
            st.setString(1, currentYear);
            ResultSet rs = st.executeQuery();
            // add each id to IDS.
            while (rs.next()) {
                filesToDownload.add(rs.getString("product_id"));
                filesToPreview.add(rs.getString("product_id"));
                filesToUpload.add(rs.getString("product_id"));
            }
            conn.close();

        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        /*
         * Distribute IDS to several threads.
         */

        //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();
            }
        }


    }

I can spot one problem with your code right away:

float completion = (queue.size()*1)/this.queueSize;

What's the point of *1 ? Both queue.size() and this.queueSize are integers. You're turning integer division into... integer division. A good compiler will probably optimize it right away. You probably meant to write something like

float completion = (queue.size() * 1.0f) / this.queueSize;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM