cancel() не работает при попытке отменить задачи в ThreadPoolExecutor Android

У меня есть несколько загрузок, которые отправляются в качестве задач на ThreadPoolExecutor. Теперь я создаю этот ThreadPoolExecutor в глобальном классе, который расширяет Application. Я храню все отправленные задачи в хэш-карте с идентификаторами.

У меня есть представление списка во фрагменте. Этот элемент представления списка содержит кнопки паузы и возобновления. Когда я нажимаю на сам элемент списка, загрузка FutureTask отправляется исполнителю глобального пула. Теперь, когда я нажимаю кнопку паузы элемента списка, я хочу, чтобы эта конкретная задача была приостановлена.

У меня есть метод onClick кнопки паузы в пользовательском адаптере моего представления списка. Итак, когда я нажимаю кнопку, в моем классе адаптера я получаю будущую задачу, связанную с этим элементом списка, по имени, а затем делаю .cancel(). Когда я проверяю значение isCancelled(), оно возвращает true. Это означает, что задача была отменена, но моя загрузка все еще продолжается, и файл загружается полностью. Как я могу это решить? Любая помощь будет оценена по достоинству.

PS: я также пытался отправлять потоки с runnable, переданным в качестве аргумента исполнителю. Затем я бы получил поток по его имени (используя пользовательский ThreadFactory, который возвращает поток с именем), а затем вызывал thread.wait() до тех пор, пока кнопка возобновления не будет нажата снова. Тоже не работает!

Вот пример кода:

Мой класс GlobalState:

    public class GlobalState extends Application{

        HashMap<String, Future<?>> futureMapMain = new HashMap<String, Future<?>>();

        ThreadPoolExecutor mainExec = new ThreadPoolExecutor(2, 2, 2000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new YourThreadFactory());

        public void submitTaskMain(String name, FutureTask<String> task){
            Future<?> longRunningTaskFuture = mainExec.submit(task);
            futureMapMain.put(name, longRunningTaskFuture);
        }

        public void cancelTaskMain(String name){
            futureMapMain.get(name).cancel(true);
            Log.e("Global State", "task cancelled?: " + futureMapMain.get(name).isCancelled());
            futureMapMain.remove(name);
        }

public void pauseTaskMain(String name){
        paused = true;
        while(paused==true){
        try {
            synchronized(futureMapMain.get(name)){
                futureMapMain.get(name).wait();
            }
        //  Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }

    public void resumeTaskMain(String name){
        paused = false;
        synchronized(futureMapMain.get(name)){
            futureMapMain.get(name).notify();
        }
    }

        public HashMap<String, Future<?>> getFutureMap(){
            return futureMapMain;
        }

        public ThreadPoolExecutor getMainExeutor(){
            return mainExec;
        }

        public class YourThreadFactory implements ThreadFactory {
            public Thread newThread(Runnable r) {
                return new Thread(r, gettName());
            }
        }
    }

Мой метод загрузки, который написан внутри моего класса фрагментов. выполняется при щелчке элемента списка:

public void abDownloadTask(){
    FutureTask<String> fTask = new FutureTask<String>(new Callable<String>() {

        @Override
        public String call() throws Exception {
            // TODO Auto-generated method stub
            for(something) {
                /* DOES SOME DOWNLOAD USING url.getcontent() with different urls in a loop and stores files to sd card. */
            }
        }
    }

    mainGs = (GlobalState) getActivity().getApplication();
    mainExec = mainGs.getMainExeutor();
    mainGs.settName(somenameforThread);
    mainGs.submitTaskMain(someNameforThread, fTask);    
}

Код адаптера моего пользовательского списка внутри кнопки паузы при нажатии кнопки:

    Runnable runnable = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub

                                    needToPause = true;
globalstate.pauseTaskMain(threadname);
            }
        }

На самом деле я предпочитаю приостанавливать и возобновлять свою задачу, используя функцию ожидания () или что-то в этом роде, а не полностью отменять задачу. Любая помощь будет оценена по достоинству. Благодарю вас!


person Shreya    schedule 14.03.2015    source источник
comment
Никакого волшебства, конечно! Ваша задача не будет отменена, если она не прослушивает отмену! Вы должны проверить прерывание потока самостоятельно.   -  person isnot2bad    schedule 14.03.2015
comment
@isnot2bad: Пожалуйста, проверьте мое редактирование. Я обновил методы паузы и возобновления в классе Globalstate. Я ставлю флаг под названием paused и, пока это правда, я жду в потоке. Разве этого недостаточно? Как я могу прослушать ждать или отменить? Спасибо!   -  person Shreya    schedule 16.03.2015
comment
Ваш метод cancelTaskMain кажется правильным, но отмена — это кооперативная вещь, поэтому ваша задача также должна прослушивать отмену и делать что-то, чтобы она работала. pauseTaskMain совершенно неверно. Вы не можете просто приостановить задачу — все, что вам нужно сделать, это приостановить поток, который вызывает pauseTaskMain.   -  person isnot2bad    schedule 16.03.2015
comment
@isnot2bad: Хорошо, может быть, я смогу прослушать значение isCanceled() этой задачи. Можно ли как-то приостановить и возобновить задачу вместо ее полной отмены? Благодарю вас!   -  person Shreya    schedule 17.03.2015
comment
Нет! Правильная отмена задачи выполняется путем проверки состояния прерывания задачи! См. docs.oracle.com/javase/tutorial/essential/concurrency/ или ibm.com/developerworks/library/j-jtp05236 подробности!   -  person isnot2bad    schedule 17.03.2015