Пул потоков в связке с асинхронными задачами

334
08 сентября 2017, 20:29

Я начал изучать многопоточность и столкнулся с проблемой что ExecutorService не работает в связке с ассинхронными задачами.

Схематично нарисовал свой проект.

Когда нажимаешь на кнопку запускатся startService в Нем срабатывает onStartCommand после идут 3 ассихнронных интернет запроса. Я сделал их путем sincroinzed синхронными.

После запуска 1 функции запускается 2, затем 3, за ним 4 и в конце запускается отдельный поток.

Используя ExecutorService я попытался нажать несколько раз на кнопку результат все перемещалось.

Поэтому я ищу выход из этой ситуации.

Что я ожидаю:

Когда я нажимаю на кнопку 1 раз или 10 не важно. То создается пул потоков в потоке запускается 1 блок.

Но остальные потоки не должны работать пока не закончится текущий поток который выполнит весь цикл нарисованный красным квадратом.

Как только текущий поток закончит работу, то должна быть проверка нет ли в очереди других потоков, если есть то по новой следующий поток должен выполнит тоже самое с 1 блока по 5 блока и т.д.

ExecutorService видимо не подойдет для этого так как он работает только с Thread. А как видимо на схеме у меня все в перемещку.

Код

public class ServiceOfflineLoader extends Service {
    private ModelSubCategoriesItems.CoursesBean coursesBean;
    private CourseDetailItem courseDetailItem;
    private LessonCourseAccess lessonCourseAccess;
    private List<String> listLessonFile=new ArrayList<>();
    private List<VideoItem> listVideoItem=new ArrayList<>();
    private List<Response> listVideoSubtitle=new ArrayList<>();
    private String strCourseID="";
    private int indexLessonRequest=0;
    private Realm realm;
    private String strUrlVideo="";
    private String strUrlSubtitle="";
    private String strFileVideoName="";
    private String strFileSubtitle="";
    private OfflineDataRealm offlineDataRealm;
    private Gson gson;
    private String strJson="";
    private SharedPrefHelper sharedPrefHelper;
    private ExecutorService executorService;
    public ServiceOfflineLoader() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public void onCreate() {
        super.onCreate();
        sharedPrefHelper=new SharedPrefHelper(this);
        gson=new Gson();
        executorService= Executors.newFixedThreadPool(1);
        EventBus.getDefault().register(this);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("ServiceOfflineLoader=onStartCommand", "START SERVICE" + "");
        if (intent!=null){
            Bundle bundle=intent.getExtras();
            coursesBean= (ModelSubCategoriesItems.CoursesBean) bundle.getSerializable(GlobalConstants.INTENT_COURSE_BEAN);
            RequestsRB.requestCourseItemDetail(this, coursesBean.id);
        }
        return super.onStartCommand(intent,flags,startId);
    }
    class LoaderThread extends Thread{
        @Override
        public void run() {
            super.run();
            Log.e("LoaderThread=run", "Run1" + "");
            realm= Realm.getDefaultInstance();
            try{
                offlineDataRealm= new OfflineDataRealm();
                for (int i = 0; i < listLessonFile.size(); i++) {
                    Response response=listVideoItem.get(i).getResponse();
                    strUrlVideo=response.getLink().get(0).getFile();
                    strFileVideoName=strUrlVideo;
                    strFileVideoName=strFileVideoName.substring(strFileVideoName.lastIndexOf('/')+1);
                    File fileVideo= new File(getFilesDir() + "/"+strFileVideoName);
                    Utils.donwloadUrlToSaveFile(strUrlVideo,fileVideo);
                    for (int j = 0; j < response.getCaptions().size(); j++) {
                        Caption caption=response.getCaptions().get(j);
                        strUrlSubtitle=caption.getFile();
                        strFileSubtitle=strUrlSubtitle;
                        strFileSubtitle=strFileSubtitle.substring(strFileSubtitle.lastIndexOf('/')+1);
                        File fileSubtitle= new File(getFilesDir() + "/"+strFileSubtitle);
                        Utils.donwloadUrlToSaveFile(strUrlSubtitle,fileSubtitle);
                    }
                    RealmString realmStringVideoItem=new RealmString();
                    strJson=gson.toJson( listVideoItem.get(i) );
                    realmStringVideoItem.setValue(strJson);
                    offlineDataRealm.strJsonVideoItem.add(realmStringVideoItem);
                    RealmString realmStringVideoSubtitle=new RealmString();
                    strJson=gson.toJson( listVideoItem.get(i).getResponse() );
                    realmStringVideoSubtitle.setValue(strJson);
                    offlineDataRealm.strJsonVideoSubtitle.add( realmStringVideoSubtitle );
                }
                strJson=gson.toJson(coursesBean);
                offlineDataRealm.strJsonModelSubCategoriesItems=strJson;
                strJson=gson.toJson(lessonCourseAccess);
                offlineDataRealm.strJsonResponseBodyAccess =strJson;
                strJson=gson.toJson(courseDetailItem);
                offlineDataRealm.strJsonCourseDetailItem=strJson;
                realm.beginTransaction();
                realm.copyToRealm(offlineDataRealm);
                realm.commitTransaction();
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                realm.close();
            }
            Log.e("LoaderThread=run", "Close Run" + "");
        }
    }
    @Subscribe
    public void onMessageEvent(MessageEvent event) {
        switch (event.message) {
            case RESPONSE_COURSE_DETAIL:
                Log.e("ServiceOfflineLoader=onMessageEvent", "RESPONSE!!!!!!!!" + "");
                courseDetailItem= (CourseDetailItem) event.link;
                RequestsRB.getAccessCourse(this, coursesBean.id, sharedPrefHelper.getUserLanguage(), GlobalConstants.TOKEN);
                break;
            case RESPONSE_GET_COURSE_ACCESS:
                ResponseBody responseBody=(ResponseBody) event.link;
                try {
                    lessonCourseAccess=new Gson().fromJson(responseBody.string(),LessonCourseAccess.class);
                } catch (IOException e) { e.printStackTrace(); }
                filterCourseAccess();
                strCourseID=courseDetailItem.getResponse().getCourseID();
                listLessonFile.clear();
                listVideoItem.clear();
                listVideoSubtitle.clear();
                indexLessonRequest=0;
                for (Map.Entry<String,ChaptersBean> entry: lessonCourseAccess.response.chapters.entrySet()) {
                    for (int i = 0; i < entry.getValue().lessons.size(); i++) {
                        listLessonFile.add( entry.getValue().lessons.get(i).lessonId );
                    }
                }
                for (int i = 0; i < listLessonFile.size(); i++) {
                    RequestsRB.requestVideo(this, strCourseID, listLessonFile.get(i),sharedPrefHelper.getUserLanguage());
                }
                break;
            case RESPONSE_VIDEO_ITEM:
                VideoItem videoItem= (VideoItem) event.link;
                listVideoItem.add(videoItem);
                listVideoSubtitle.add( videoItem.getResponse() );
                indexLessonRequest++;
                if (indexLessonRequest==listLessonFile.size()){
                    LoaderThread loaderThread =new LoaderThread();
                    executorService.execute(loaderThread);
                    indexLessonRequest=0;
                }
                break;
        }
    }
    private void filterCourseAccess() {
        boolean isCourseAccess = lessonCourseAccess.response.isAccess;
        if (!isCourseAccess){
            Map.Entry<String,ChaptersBean> firstChapterBean=lessonCourseAccess.response.chapters.entrySet().iterator().next();
            lessonCourseAccess.response.chapters.clear();
            ChaptersBean chaptersBean=firstChapterBean.getValue();
            List<ChaptersBean.LessonsBean> lessonsBeans=new ArrayList<>();
            for (int i = 0; i < chaptersBean.lessons.size(); i++) {
                if (i==3){
                    break;
                }
                lessonsBeans.add( chaptersBean.lessons.get(i) );
            }
            chaptersBean.lessons.clear();
            chaptersBean.lessons.addAll( lessonsBeans );
            lessonCourseAccess.response.chapters.put(firstChapterBean.getKey(),chaptersBean);
        }
    }
}
READ ALSO
Помогите упростить функцию

Помогите упростить функцию

Помогите упростить функцию drawRect(int w, int h);Понимаю, костыли за костылями, но на ошибках учатся

269
The import java.swing cannot be resolved

The import java.swing cannot be resolved

При попытке подключить swing пишет такое

336
Можно ли присваивать класс тегу &lt;br&gt;?

Можно ли присваивать класс тегу <br>?

Вопрос по сути глупый, поэтому не сильно хочется тратить время еще и на объяснение ситуации, где мне это понадобилосьПросто интересно, насколько...

259