Лакшман Прасад был прав, pip --upgrade
и / или virtualenv --no-site-packages
- это путь. Удаление общесистемных модулей python является плохим.
Параметр - upgrade
для pip устанавливает установленные модули в виртуальном env, даже если они уже существуют в системной среде, и даже если требуемая версия или последняя доступная версия совпадает с версией системы.
pip --upgrade install
И использование опции -no-site-packages при создании виртуальной среды гарантирует, что отсутствующие зависимости не могут возможно, замаскированы наличием недостающих модулей в системном пути. Это помогает выявлять проблемы при миграции модуля из одного пакета в другой, например. pinax.apps.groups -> django-groups, особенно когда проблема связана с инструкциями load templatetags в django, которые ищут все доступные модули для каталогов templatetags и определения тегов внутри.
Я знаю, что перезапустить использованный объект Java Thread невозможно, но я не нашел объяснения, почему это не разрешено; даже если гарантировано, что поток завершен (см. примерный код ниже).
blockquote>Мое гадание состоит в том, что потоки могут быть напрямую привязаны (для эффективности или других ограничений) к фактическому native , которые могут быть перезапущены в некоторых операционных системах, но не в других. Если разработчики языка Java разрешили перезапускать Threads, они могут ограничить количество операционных систем, на которых может работать JVM.
Подумайте об этом, я не могу думать о ОС который позволяет перезапустить поток или процесс после его завершения или завершения. Когда процесс завершается, он умирает. Вы хотите другой, вы перезапустите его. Вы никогда не воскрешаете его.
. Помимо вопросов эффективности и ограничений, налагаемых базовой ОС, есть проблема анализа и рассуждений. Вы можете рассуждать о параллелизме, когда вещи либо неизменяемы, либо имеют дискретный, конечный срок службы. Как и государственные машины, они должны иметь состояние терминала. Это началось, дожидаясь, закончилось? Такие вещи не могут быть легко обоснованы, если вы разрешаете Threads воскресать.
Вы также должны учитывать последствия воскрешения потока. Восстановить свой стек, его состояние, безопасно воскресить? Можете ли вы воскресить нить, которая закончилась ненормально? И т. Д.
Слишком волосатый, слишком сложный. Все это для незначительных выгод. Лучше сохранить Threads как нересупретируемые ресурсы.
Темы Java следуют жизненному циклу, основанному на приведенной ниже диаграмме состояний. Когда поток находится в конечном состоянии, он закончен. Это просто дизайн. [/g0]
Я поставил бы вопрос наоборот: почему должен перезапустить объект Thread?
Возможно, гораздо проще рассуждать о (и, возможно, реализовать) Thread что просто выполняет свою заданную задачу ровно один раз и затем окончательно завершается. Для перезапуска потоков потребуется более сложное представление о том, какое состояние было в программе в данный момент.
Поэтому, если вы не можете найти конкретную причину, по которой перезапуск данного Thread
является лучшим вариантом, чем просто создав новый с тем же Runnable
, я бы сказал, что дизайнерское решение к лучшему.
(Это в целом похоже на аргумент о изменяемых переменных vs final
- я нахожу конечные «переменные» гораздо проще рассуждать и скорее создали бы несколько новых постоянных переменных, чем повторное использование существующих.)
restart
является стоимость создания новых (и сбор мусора старых) объектов Thread.
– Curd
27 October 2010 в 15:36
Runnable
s в пул потоков (например, ThreadPoolExecutor
).
– Andrzej Doyle
27 October 2010 в 17:51
Если вы обеспокоены накладными расходами на создание нового объекта Thread, вы можете использовать исполнители.
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class Testes {
public static void main(String[] args) {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Testes.A());
executor.execute(new Testes.A());
executor.execute(new Testes.A());
}
public static class A implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getId());
}
}
}
Запустив это, вы увидите, что тот же поток используется для всех объектов Runnable.
A Thread
не является нитью . Нить - это исполнение вашего кода. Thread
- это объект, который ваша программа использует для создания и управления жизненным циклом потока .
Предположим, вам нравится играть в теннис. Предположим, вы и ваш друг играете в действительно потрясающий набор. Как бы ваш друг отреагировал, если бы вы сказали: «Это было невероятно, давайте снова сыграем». Ваш друг может подумать, что вы с ума сошли. Не имеет смысла даже говорить о том, чтобы снова играть в один и тот же набор. Если вы снова играете, вы играете в другой набор.
Нить - это исполнение вашего кода. Не имеет смысла даже говорить о «повторном использовании» потока исполнения по той же причине, что бессмысленно говорить о повторном воспроизведении того же набора в теннисе. Даже если другое выполнение вашего кода выполняет все те же операторы в том же порядке, это все еще исполнение .
Анджей Дойл спросил: «Почему вы хотите для повторного использования Thread
? " Почему? Если объект Thread
представляет поток выполнения --- эфемерная вещь, о которой вы даже не можете говорить о повторном использовании, то зачем вам или ожидать объект Thread
для повторного использования?
Вы можете обойти это, либо используя java.util.concurrent.ThreadPoolExecutor
, либо вручную, имея поток, который вызывает Runnable.run()
для каждого Runnable
, который ему задан, а не фактически выходит, когда он закончен.
Это не совсем то, о чем вы спрашивали, но если вы беспокоитесь о времени строительства нити, это может помочь решить эту проблему. Вот пример кода для ручного метода:
public class ReusableThread extends Thread {
private Queue<Runnable> runnables = new LinkedList<Runnable>();
private boolean running;
public void run() {
running = true;
while (running) {
Runnable r;
try {
synchronized (runnables) {
while (runnables.isEmpty()) runnables.wait();
r = runnables.poll();
}
}
catch (InterruptedException ie) {
// Ignore it
}
if (r != null) {
r.run();
}
}
}
public void stopProcessing() {
running = false;
synchronized (runnables) {
runnables.notify();
}
}
public void addTask(Runnable r) {
synchronized (runnables) {
runnables.add(r);
runnables.notify();
}
}
}
Очевидно, это просто пример. Он должен иметь лучший код обработки ошибок и, возможно, больше настроек.
Потому что они не создали его таким образом. С ясной точки зрения это имеет смысл для меня. Thread представляет поток выполнения, а не задачу. Когда эта последовательность выполнения завершена, она выполнила свою работу, и она просто замалчивала все, чтобы она начиналась сверху.
С другой стороны, Runnable представляет задачу и может быть передана многим Потоки столько раз, сколько хотите.
Почему вы не хотите создавать новую тему? Если вы обеспокоены накладными расходами на создание своего объекта MyThread, сделайте его Runnable и запустите его с помощью new Thread(myThread).start();
Runnable
(или некоторым другим командным объектом) для запуска. Как только он заканчивается, закрывающая нить переходит в режим сна, пока не получит / не получит другую. Или пул потребительских пользовательских потоков, потребляющих Runnable
объекты, помещенные в очередь.
– luis.espinal
27 October 2010 в 15:21
java.lang.Thread
) никогда не заканчивается, он просто ждет, когда это будет сделано, пока не получит новый Runnable
. Создаются только Runnable
и GCed, и они могут быть такими же легкими, как вам нужно.
– sleske
27 October 2010 в 16:35
Я искал то же самое решение, которое вы, похоже, ищете, и я решил его таким образом. если вы обнаружите событие mousePressed, вы можете его закончить и повторно использовать, но его нужно инициализировать, как показано ниже.
class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent e) {
if(th.isAlive()){
th.interrupt();
th = new Thread();
}
else{
th.start();
}
}
}