2012-04-26 2 views
0

Можно создать дубликат:
Java: “implements Runnable” vs. “extends Thread”новая тема (Runnable runnableObj) Vs. расширяет Thread

Я просто интересен, есть некоторые тонкие различия между созданием своего собственного объекта, который расширяет тему и создание потока с помощью ниток (Runnable) конструктор?

У меня есть код, который отлично работает, когда я использую классы, которые расширяют Thread, но если я попытаюсь использовать логику, которая создает Threads, используя конструктор Thread (Runnable), новые потоки, похоже, не работают должным образом - t обнаруживают, что они живы так же, как когда я использую пользовательские подклассы, которые я создал, и они, кажется, не заканчиваются.

В моем коде я просто создаю несколько потоков, затем просматриваю список моих тем, чтобы найти тот, который жив, и присоединяется к нему, пока он не умрет. Затем я снова ищу поток в списке, который жив и присоединяется к нему. Это продолжается до тех пор, пока все нити не умрут.

Спасибо за чтение.

+0

Это дубликат, хотя вы можете показать свой код (и изменить название), чтобы сделать его уникальным. – Gray

ответ

2

A Thread - это ресурс для выполнения работы. Runnable - это часть работы. Вы создаете новый тип ресурса или просто определяете работу, которую хотите сделать?

Чтобы «завершить» поток, который вы просто возвращаете из метода «run». Вам нужно будет увидеть пример вашего кода, чтобы понять, что вы имеете в виду, чтобы не сказать, активны ли они.

Создание Runnables также, конечно, упрощает реорганизацию кода для использования ThreadPool в будущем.

2

В моем коде я просто создаю несколько потоков, затем просматриваю список моих тем, чтобы найти тот, который жив, и присоединяется к нему, пока он не умрет.

Как (и почему) вы «просматриваете мой список тем»? Я бы вместо того, чтобы добавить Thread в какой-то Collection, что вы затем можете итерацию по горизонтали и присоединиться к каждому Thread в свою очередь:

List<Thread> threads = new ArrayList<Thread(); 
    for (int i = 0; i < 100; i++) { 
    Thread thread = new Thread(new Runnable() ...); 
    thread.start(); 
    threads.add(thread); 
    } 
    ... 
    for (Thread thread : threads) { 
     thread.join(); 
    } 

Еще лучше было бы использовать один из ExecutorService с заданных Executors. У них есть много возможностей для создания пулов потоков и ожидания полного завершения пула. Почти всегда рекомендуется более new Thread(...).

Я не могу обнаружить, что они живы точно так же, как при использовании пользовательских подклассов я сделал

Если вы пытаетесь установить имя Thread, то вы можете Не делайте этого в конструкторе вашего Runnable. Вы может однако сделать это в run() способ. Вы можете сделать:

new Thread(new Runnable() { 
     public void run() { 
      Thread.currentThread().setName("..."); 
     } 
    }); 

В противном случае, я не знаю, почему вы не видели бы ваши Thread, если оно уже не закончил.

они, кажется, не кончаются, никогда.

Runnable Используя нить заканчивается, когда run() метод возвращает - либо через return или throw. Это очень похоже на расширение Thread, поэтому я не уверен, почему это не сработает.

1

Я бы порекомендовал использовать concurrency utility и не пытаться управлять своими потоками, которые сложны и подвержены ошибкам. Использование параллельного api также поможет вам сразу же применить правильные шаблоны.