Остановка потока

  • Работает с любыми повторяемыми
  • Внутренние данные - это объект-генератор (не список)
  • Один вкладыш
In [259]: get_in_chunks = lambda itr,n: ( (v for _,v in g) for _,g in itertools.groupby(enumerate(itr),lambda (ind,_): ind/n))

In [260]: list(list(x) for x in get_in_chunks(range(30),7))
Out[260]:
[[0, 1, 2, 3, 4, 5, 6],
 [7, 8, 9, 10, 11, 12, 13],
 [14, 15, 16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25, 26, 27],
 [28, 29]]
5
задан skaffman 19 June 2009 в 10:18
поделиться

4 ответа

Stopping a thread is probably the wrong way to look at. The actual resource consumed by a single thread on a desktop machine is irrelevant. Think of it as aborting the download.

If the read is blocking, then that isn't really much of a problem. You can wait until there is some data before not reading again. A more abrupt approach would be to call close on the stream (from another thread).

6
ответ дан 18 December 2019 в 13:18
поделиться

Вам нужно проверить наличие флага остановки где-нибудь в вашей процедуре загрузки.

public DownloadThread implements Runnable {
    private boolean stop;
    public void stop() { stop = true; }
    public void run() {
        while (!stop) {
            // download a block, save it somewhere
        }
    }
}

Конечно, здесь отсутствует необходимая синхронизация, но речь идет о том, как остановить поток без использования устаревшего потока .stop () .

4
ответ дан 18 December 2019 в 13:18
поделиться

Я предлагаю вам сделать то, что предложил Бомб (с изменчивой переменной), и просто оставить поток умирать в фоновом режиме, возвращая управление обратно пользователю. Он может потратить немного времени на выборку последнего блока, но если пользователь может продолжать делать что-то еще, это не имеет большого значения. Если размеры ваших блоков были относительно небольшими, пропускная способность не будет слишком большой, и данные ввода-вывода в конечном итоге будут отключены и вернутся, если соединение ухудшилось.


public class Downloader {
    protected final AtomicBoolean run = new AtomicBoolean(false);
    protected final byte[] file;
    protected volatile double progress = 0.0;    

    public download(URL url) {
        run.set(true);
        new Thread() {
            @Override
            public run() {
                final ByteBuffer buffer = new ByteBuffer();
                while(run) {
                    /* download chunk, e.g add to buffer, or whatever */
                    buffer.put(chunk);
                    progress = buffer.size().size() / fileTotalSize; //e.g
                }
                syncrhonized(Downloader.this) {
                    file = buffer.array();
                }
            }
        }.start();
    }

    public void abort() {
        run.set(false);
    }

    public double getProgress() {
        return progress;
    }

    public synchronized byte[] getFile() {
        return file;
    }
}
1
ответ дан 18 December 2019 в 13:18
поделиться

Во-первых, операция stop () для java.util. Thread устарел, и его использование настоятельно не рекомендуется, так как оно может оставить вещи в нестабильном состоянии. Гораздо предпочтительнее, чтобы вы отправляли сообщение Runnable потока с просьбой о его безопасном останове.

Проблема в том, что ваш поток выполняет блокирующие операции ввода-вывода, и поэтому он не получит ваше сообщение до тех пор, пока I / O завершен.

Лучшее, на что вы можете надеяться, если кто-то другой не предложит лучший вариант, - это interrupt () Thread и надеяться, что классы ввода-вывода заметят и остановят загрузку.

Изменить: javadoc для Thread.interrupt () действительно говорит, что ввод / вывод может быть прерван, если вы используете java.nio, но это очень маловероятно. «Нормальный» трафик java.io блокируется и не может быть прерван.

Почему Thread.stop, Thread.suspend и Thread. возобновить Устарело?

3
ответ дан 18 December 2019 в 13:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: