Почему мои темы все еще активны после моей попытки закрыть их?

В моем классе есть следующие функции: https://codeshare.io/kvze0

public void startFtp(String address, int port, String username, String password, String filepath, String file)
{
    //...parsing parameter to class variables
    try {
        while (download) {
            downloadAndBroadcast();
        }
    } catch (Exception e){
        Log.d(TAG, "startFtp disconnected or fails");
        e.printStackTrace();
    }
}

private void downloadAndBroadcast() {
    beginTime = System.currentTimeMillis();
    try {
        URL url = new URL("http://" + serverAddress + "/" + serverFile);
        URLConnection urlConnection = url.openConnection();
        urlConnection.connect();
        inputStream = new BufferedInputStream(url.openStream());
        long difference;
        byte data[] = new byte[4094];
        int count;
        while ((count = inputStream.read(data)) != -1 && download) {
            downloadCount += count;
            long stoptime = System.currentTimeMillis();
            difference = stoptime - beginTime;
            if (difference > 1000 && download) {
                currentSpeed = downloadCount / (difference / 1000L);
                averageSpeed = (averageSpeed + currentSpeed) / 2;
                broadcastSpeed();
                downloadCount = 0; 
                beginTime = stoptime;
            }
        }
        clearInputStream();
    } catch (Exception e) {
        Log.d(TAG, "FAIL");
        e.printStackTrace();
    } finally {
        clearInputStream();
        Log.d(TAG, "downloadAndBroadcast: finally");
    }
}


private void broadcastSpeed() {
    Log.d(TAG, "broadcastSpeed: ");
    toMainActivityIntent = new Intent(Constants.BROADCAST_SPEED)
            .addCategory(Intent.CATEGORY_DEFAULT)
            .putExtra("speed", averageSpeed)
            .putExtra("thread", String.valueOf(Thread.currentThread().getId()));

    downloadService.sendBroadcast(toMainActivityIntent); //send to main activity, in main activity, there is a listener that analyzes Broadcast and Intent
}
private void clearInputStream() {
    if (inputStream != null) {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public void stopDownload() {
    Log.d(TAG, "stopDownload: ");
    download = false;
}

Я вызываю stopDownload(), чтобы остановить потоки. После этого я регистрирую свой ThreadPoolExecutor, чтобы увидеть статусы потоков:

[Shutting down, pool size = 4, active threads = 4, queued tasks = 0, completed tasks = 0]

Что делает мои темы активными? Заранее спасибо.

Как я начинаю тему:

    int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();

    executor = new ThreadPoolExecutor(
            NUMBER_OF_CORES * 2,
            NUMBER_OF_CORES * 2,
            60L,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>()
    );
    executor.execute(new Runnable() {
        public void run() {
            FTPDownloader ftpDownloader = new FTPDownloader(downloadService);
            ftpDownloader.startFtp(server.getServer(), server.getPort(), server.getUser(), server.getPass(), server.getPath(), server.getFiledl());
            if (Thread.interrupted()) {
                Log.d(TAG, "run: ");
                ftpDownloader.stopDownload();
            }
        }
    });

Я вызываю executor.shutdownNow();, чтобы закрыть свои темы:

private class MainActivityReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
            executor.shutdownNow();       
    }
}

person phuwin    schedule 01.08.2016    source источник
comment
Я думаю, вам было бы лучше с AsyncTask. Но в любом случае - я не вижу вызова shutdownNow() и как он должен вызывать stopDownload?   -  person Fildor    schedule 01.08.2016
comment
Вызов @Fildor для shutdownNow() вызывается в другой функции.   -  person phuwin    schedule 01.08.2016
comment
Я думал, что у меня есть ответ, но я понял, что это неправильно... Можете ли вы проверить, что флаг загрузки действительно установлен на false? Я так не думаю.   -  person Fildor    schedule 01.08.2016
comment
О, и в своем вопросе вы пишете: я вызываю stopDownload(), чтобы остановить потоки, что правильно? Вы вызываете stopDownload или завершаете работу Исполнителя?   -  person Fildor    schedule 01.08.2016
comment
@Fildor Я только что проверил свой журнал. Вы правы в том, что stopDownload() не звонили. Я думал, что при вызове shutDownNow() он прервет все потоки в пуле. Здесь упоминается: stackoverflow.com/questions/15900387/   -  person phuwin    schedule 01.08.2016
comment
Да, это так. Но вы поймаете InterruptedException как исключение внутри downloadAndBroadcast, которое сбросит статус прерывания. Затем, вернувшись в startFTP, он просто продолжит цикл, потому что загрузка по-прежнему верна. Однако он должен напечатать трассировку стека. Вы можете попробовать добавить блок catch перед catch(Exception) с помощью catch(InterruptedException), в котором вы просто устанавливаете download=false;   -  person Fildor    schedule 01.08.2016


Ответы (1)


Попробуйте выполнить следующие действия:

Избавьтесь от этих строк:

if (Thread.interrupted()) {
            Log.d(TAG, "run: ");
            ftpDownloader.stopDownload();
        }

В downloadAndBroadcast добавьте это перед } catch (Exception e) {

} catch (InterruptedException ie) {
    // catching IE will reset interrupted status. So just clear the flag.
    download = false;
}
person Fildor    schedule 01.08.2016