3

My class has these functions: 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;
}

I call stopDownload() to stop the threads. After that I log my ThreadPoolExecutor to see the threads' statuses:

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

What makes my threads active? Thanks in advance.

How I start a thread:

    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();
            }
        }
    });

I call executor.shutdownNow(); to shut my threads down:

private class MainActivityReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
            executor.shutdownNow();       
    }
}
phuwin
  • 3,130
  • 4
  • 26
  • 49
  • I guess you would have been better off with AsyncTask. But anyway - I cannot see the call to `shutdownNow()` and how is that supposed to call `stopDownload`? – Fildor Aug 01 '16 at 11:06
  • @Fildor call to shutDownNow() is called in another function. – phuwin Aug 01 '16 at 11:10
  • I thought I had the answer, but I realized it was wrong... Can you verify the download flag is actually set to false? I don't believe so. – Fildor Aug 01 '16 at 11:19
  • Oh, and in your question you write: "I call stopDownload() to stop the threads" which is correct? You call stopDownload or shutdown the Executor? – Fildor Aug 01 '16 at 11:20
  • @Fildor I just checked my log. You are right about `stopDownload()` hasn't been called. I thought when `shutDownNow()` is called, it will interrupt all the threads in the Pool. It is mentioned here: http://stackoverflow.com/questions/15900387/how-to-stop-all-runnable-thread-in-java-executor-class – phuwin Aug 01 '16 at 11:26
  • 1
    Yes it does. But you catch the InterruptedException as Exception inside downloadAndBroadcast which will reset the interrupted status. Then back in startFTP it will just continue the loop because download is still true. It should print a stacktrace, though. You can try and add a catch-block before catch(Exception) with `catch(InterruptedException)` in which you simply set `download=false;` – Fildor Aug 01 '16 at 11:30

1 Answers1

1

Try the following steps:

Get rid of these lines:

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

In downloadAndBroadcast add this before } catch (Exception e) {

} catch (InterruptedException ie) {
    // catching IE will reset interrupted status. So just clear the flag.
    download = false;
}
Fildor
  • 14,510
  • 4
  • 35
  • 67