Java 使1个线程等待线程数组完成

Java 使1个线程等待线程数组完成,java,arrays,multithreading,Java,Arrays,Multithreading,我有一个称为workers的线程数组。还有另一个单独的线程称为status 两个线程都访问共享的LinkedBlockingQueue。Workers(线程数组)使用poll()来拉取工作,并每隔30秒报告一次队列的大小 运行此命令时遇到的问题是,我从status类中打印了以下内容: 上传 预览 但是预览应该出现在上传之前,而且只能出现在上传之前。 那么,我认为我的状态对象不是等待第一批工人完成吗 我想要这个: 下载 预览 上传 但事实上,事情有点不同步 // start up the Stat

我有一个称为workers的线程数组。还有另一个单独的线程称为status

两个线程都访问共享的LinkedBlockingQueue。Workers(线程数组)使用poll()来拉取工作,并每隔30秒报告一次队列的大小

运行此命令时遇到的问题是,我从status类中打印了以下内容:

上传

预览

但是预览应该出现在上传之前,而且只能出现在上传之前。 那么,我认为我的状态对象不是等待第一批工人完成吗

我想要这个:

下载

预览

上传

但事实上,事情有点不同步

// 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();
//启动状态对象类。
int downloadSize=filesToDownload.size();
线程状态线程=新线程(新状态(filesToDownload,currentYear,downloadSize,“DOWNLOADING…”);
statusThread.start();
/**
*下载文件
*/
线程[]工作线程=新线程[线程数];
对于(int x=0;x<线程数;x++){
workers[x]=新线程(新的S3ObjectDownloader(filesToDownload,currentYear));
workers[x].start();
}
对于(int x=0;x<线程数;x++){
试一试{
workers[x].join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
/**
*创建预览
*/
int previewSize=filesToPreview.size();
statusThread=新线程(新状态(filesToPreview、currentYear、previewSize、“PREVIEWING…”);
statusThread.start();
工人=新线程[线程数];
对于(int x=0;x<线程数;x++){
workers[x]=新线程(新Worker(filesToPreview,当前年份));
workers[x].start();
}
对于(int x=0;x<线程数;x++){
试一试{
workers[x].join();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
/**
*将预览上传到S3。
*/
//我们需要TransferManager进行上传。
TransferManager txManager=新的TransferManager(新的类路径属性FileCredentialsProvider());
statusThread=新线程(新状态(filesToUpload,currentYear,filesToUpload.size(),“Upload…”);
statusThread.start();
工人=新线程[线程数];
对于(int x=0;x<线程数;x++){
workers[x]=新线程(新的S3ObjectUploader(filesToUpload,currentYear,txManager));
workers[x].start();
}
对于(int x=0;x<线程数;x++){
试一试{
workers[x].join();
}捕获(中断异常e){
//TODO自动生成的捕获
//挡块
e、 printStackTrace();
}
}
//关闭传输管理器
txManager.shutdownNow();
下面是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();
            }
        }

    }

}
公共类状态实现可运行{
私人字符串会议年;
专用队列;
私有整数队列大小;
私有字符串jobeName;
公共状态(队列队列、字符串conferenceYear、int queueSize、字符串jobName){
this.conferenceYear=conferenceYear;
this.queue=队列;
this.queueSize=queueSize;
this.jobeName=jobName;
}
@凌驾
公开募捐{
而(!queue.isEmpty()){
试一试{
浮点完成=(queue.size()*1.0f)/this.queueSize;
System.out.println(this.jobeName+“:”+this.conferenceYear+“剩余…”+MessageFormat.format(“{0,number,#.##%}”,completion));
时间单位。秒。睡眠(30);;
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}

Java有倒计时锁来支持这种场景

看看课堂

该链接还包含一个很容易理解的示例实现。您可以为每个任务创建闩锁,以指示开始和等待结束