ThreadPoolExecutor для запуска AbortableHttpRequest - как вызвать abort? - PullRequest
0 голосов
/ 18 января 2012

Я запускаю сетевой сервис в Android, где я направляю все свои http-запросы на выполнение и получаю обратные вызовы от сервиса, когда запросы завершены. Я запускаю запросы в ThreadPoolExecutor , чтобы ограничить количество одновременных запросов. Когда запросы выполняются в пуле, они в конечном итоге создают HttpGet или HttpPost, которые косвенно реализуют AbortableHttpRequest , что позволяет отменить соединение (скажем, если оно блокируется в течение длительного времени).

Если пользователь отменяет запрос, я бы хотел как-то детализировать очередь потоков и вызвать процедуру прерывания для этого запроса. Если, например, веб-сайт не отвечает, и пользователь решает сделать что-то еще, сейчас мой единственный вариант - дождаться наступления стандартного 5-минутного тайм-аута http для этого зависшего запроса, прежде чем этот поток освободится. Если бы я мог получить доступ к потоку, в котором есть мой запрос, и вызвать прерывание, это сразу же освободило бы вещи.

Из того, что я могу понять, кажется, что как только мой запрос поступил в пул потоков, это черный ящик, пока он не выйдет на другом конце. Запрос очереди приведет только к возврату фьючерсов, что скрывает работоспособность.

Есть ли лучший подход для этого? Я довольно плохо знаком с Java и многопоточностью (в основном я использую Perl, который не очень хорошо работает с потоками).

1 Ответ

2 голосов
/ 18 января 2012

То, что вы даете задачу исполнителю пула потоков, не означает, что вы не можете хранить ссылку на него.Сохраните ссылку на задачу, и если пользователь решит отменить ее, вызовите abort для вашей задачи.

public class MyAbortableRunnable implements Runnable {
    private final Object lock = new Object();
    private AbortableHttpRequest request;

    public void abort() {
        synchronized(lock) {
            if (request != null) {
                request.abort();
            }
        }
    }

    @Override
    public void run() {
        ...
        // create the request
        synchronized(lock) {
            this.request = ...;
        }
        ...
    }
}
...