加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – ThreadPoolExecutor:获取正在执行的特定Runnable

发布时间:2020-12-15 02:18:15 所属栏目:Java 来源:网络整理
导读:我正在使用ThreadPoolExecutor在后台执行多个长时间运行的任务,ThreadPoolExecutor的池大小为4,因此当添加超过4个任务时,它们被推送到队列,当4个任务中的一个完成时,一个任务从队列中执行以执行. 我想知道有没有办法访问当前正在执行但不在队列中的Runnable
我正在使用ThreadPoolExecutor在后台执行多个长时间运行的任务,ThreadPoolExecutor的池大小为4,因此当添加超过4个任务时,它们被推送到队列,当4个任务中的一个完成时,一个任务从队列中执行以执行.

我想知道有没有办法访问当前正在执行但不在队列中的Runnable对象,即前4个任务.

目的:我想在任何给定点获取任务的当前状态,在mThreadPoolExecutor.getQueue()的帮助下我正在访问排队并准备执行的任务,请建议我访问当前正在执行的任务这样我就可以在需要时附加和删除它上面的监听器/处理程序.

我的Runnable类:

public class VideoFileUploadRunner implements Runnable {

    private final VideoFileSync mVideoFileSync;
    private final DataService dataService;

    private Handler handler;

    public VideoFileUploadRunner(VideoFileSync videoFileSync,DataService dataService) {
        this.mVideoFileSync = videoFileSync;
        this.dataService = dataService;

    }

    public int getPK()
    {
        return  mVideoFileSync.get_idPrimaryKey();
    }

    public void setHandler(Handler handler) {
        this.handler = handler;
    }

    @Override
    public void run() {
        try {

            if (mVideoFileSync.get_idPrimaryKey() < 0) {
                addEntryToDataBase();
            }
            updateStatus(VideoUploadStatus.IN_PROGRESS);
            FileUploader uploader = new FileUploader();
            updateStatus(uploader.uploadFile(mVideoFileSync.getVideoFile()));



        } catch (Exception e) {
            updateStatus(VideoUploadStatus.FAILED);
            e.printStackTrace();
        }
    }

    private void addEntryToDataBase() {
        int pk = dataService.saveVideoRecordForSync(mVideoFileSync);
        mVideoFileSync.set_idPrimaryKey(pk);
    }

    private void updateStatus(VideoUploadStatus status) {
        if (handler != null) {
            Message msg = new Message();
            Bundle b = new Bundle();
            b.putString(AppConstants.Sync_Status,status.toString());
            msg.setData(b);
            handler.sendMessage(msg);
        }
        dataService.updateUploadStatus(mVideoFileSync.get_idPrimaryKey(),status.toString());


    }
}

在任务进度列表视图持有者中:

public void setData(VideoFileSync fileSync) {
        tvIso.setText(fileSync.getVideoFile().getISO_LOOP_EQUP());
        tvUnit.setText(fileSync.getVideoFile().getUnit());
        tvName.setText(fileSync.getVideoFile().getLocalPath());
        tvStatus.setText(fileSync.getCurentStatus().toString());
        addHandleForUpdate(fileSync);
    }

    private void addHandleForUpdate(VideoFileSync fileSync) {

        Handler.Callback callBack = new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if(msg.getData()!=null)
                {
                    tvStatus.setText(msg.getData().getString(AppConstants.Sync_Status));

                }
                return false;
            }
        };
        mHadler = new Handler(Looper.getMainLooper(),callBack);

        VideoFileUploadRunner runner = VideoUploadManager.getInstance().getRunnerForSyncFile(fileSync);
        if(runner!=null)
        runner.setHandler(mHadler);
    }

在VideoUploadManager中我有以下方法返回Runnable对象,在这里我需要帮助,以便我可以返回当前正在执行的任务.

public synchronized VideoFileUploadRunner getRunnerForSyncFile(VideoFileSync fileSync) {
        Iterator<Runnable> itr = mThreadPoolExecutor.getQueue().iterator();
        while (itr.hasNext()) {
            VideoFileUploadRunner runner = (VideoFileUploadRunner) itr.next();
            if (runner.getPK() == fileSync.get_idPrimaryKey()) {
                return runner;
            }
        }
        return null;

    }

解决方法

最好的方法是公开一个同步变量,其中包含当前正在执行的任务的信息.

public MyTask implements Runnable {
    private String id;
    private Map<String,MyTask> mapTasks;

    public MyTask(String id,Map<String,MyTask> mapTasks) {
        this.id = id;
        this.mapTasks = mapTasks;
    }

    public void run() {
         synchronized(mapTasks) {
             mapTasks.put(id,this);
         }

         ...

         synchronized(mapTasks) {
             mapTasks.remove(id);
         }
    }
}


// Create a map of tasks
Map<String,MyTask> mapTasks = new HashMap<String,MyTask>();

// How to create tasks
MyTask myTask1 = new MyTask("task1",mapTasks);
MyTask myTask2 = new MyTask("task2",mapTasks);

executorService.execute(myTask1);
executorService.execute(myTask2);

....

并打印当前正在执行的任务列表:

public void printCurrentExecutingTasks(Map<String,MyTask> tasks) {
    for (String id: tasks.keySet()) {
        System.out.println("Executing task with id: " + id);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读