Вот чистое решение html / css:
HTML
CSS
.block {
position:relative;
}
.block .overlay {
position:absolute;
left:0; top:0; bottom:0; right:0;
}
.block .inner {
position:relative;
pointer-events: none;
z-index: 1;
}
.block .inner a {
pointer-events: all;
}
Да: реализация Runnable
- это предпочтительный способ сделать это, IMO. Вы не специализируетесь на поведении потока. Вы просто даете ему что-то бежать. Это означает, что композиция является философски «более чистым» способом.
В практических терминах это означает, что вы можете реализовать Runnable
и перейти от другого класса.
С выпуском Java 8 теперь есть третий вариант.
Runnable
- функциональный интерфейс , что означает, что его экземпляры могут быть созданы с помощью лямбда выражения или ссылки на методы.
Ваш пример может быть заменен на:
new Thread(() -> { /* Code here */ }).start()
или если вы хотите использовать ExecutorService
и ссылку на метод:
executor.execute(runner::run)
Они не только намного короче, чем ваши примеры, но также обладают многими преимуществами, изложенными в других ответах на использование Runnable
по сравнению с Thread
, например, с одной ответственностью и использованием композиции, потому что вы не специализируетесь на Поведение потока. Этот способ также позволяет избежать создания дополнительного класса, если все, что вам нужно, это Runnable
, как и в ваших примерах.
() -> {}
должен представлять пользовательскую логику, которая кому-то нужна? Так лучше было бы сказать как () -> { /* Code here */ }
?
– ToolmakerSteve
5 September 2015 в 11:56
Одна вещь, которую я удивляю, еще не упоминалась, заключается в том, что реализация Runnable
делает ваш класс более гибким.
Если вы расширяете поток, то действие, которое вы делаете, всегда будет быть в потоке. Однако, если вы реализуете Runnable
, это не обязательно. Вы можете запустить его в потоке или передать его какой-либо службе-исполнителю или просто передать его как задачу в однопоточном приложении (возможно, для запуска позднее, но в пределах одного потока). Опции гораздо более открыты, если вы просто используете Runnable
, чем если бы вы привязали себя к Thread
.
Thread
, потому что Thread implements Runnable
... ;-) Но он «чувствует себя лучше». делая это с помощью Runnable
, чем с помощью Thread
!
– siegi
26 April 2012 в 22:13
Thread
добавляет много лишних вещей, которые вам не нужны, и во многих случаях не хотят. Вам всегда лучше реализовать интерфейс, который соответствует тому, что вы на самом деле делаете.
– Herms
27 April 2012 в 14:19
Кажется, все здесь думают, что внедрение Runnable - это путь, и я действительно не согласен с ними, но есть также аргументы в пользу расширения Thread, на мой взгляд, на самом деле вы его продемонстрировали в своем коде.
Если вы реализуете Runnable, то класс, который реализует Runnable, не имеет контроля над именем потока, это вызывающий код, который может установить имя потока, например:
new Thread(myRunnable,"WhateverNameiFeelLike");
но если вы расширяете Thread, тогда вы сможете управлять этим в самом классе (как в вашем примере вы называете поток ThreadB). В этом случае вы:
A) могли бы дать ему более полезное имя для целей отладки
B) заставляют использовать это имя для всех экземпляров этого класса (если вы не проигнорируете тот факт, что он является потоком и делает с ним все, как если бы он был Runnable, но мы говорим о соглашении здесь в любом случае, поэтому можем игнорировать эту возможность, которую я чувствую).
Возможно, вы даже можете возьмите трассировку стека своего создания и используйте это как имя потока. Это может показаться странным, но в зависимости от того, как структурирован ваш код, он может быть очень полезен для целей отладки.
Это может показаться небольшим, но там, где у вас очень сложное приложение с большим количеством потоков и всего внезапные вещи «остановились» (либо по причинам тупика, либо, возможно, из-за недостатка в сетевом протоколе, который был бы менее очевидным, или других бесконечных причин), а затем получить дамп стека из Java, где все потоки называются «Thread» -1 ',' Thread-2 ',' Thread-3 'не всегда очень полезен (это зависит от того, как структурированы ваши потоки и можно ли с пользой сказать, что именно по их трассировке стека - не всегда возможно, если вы используя группы из нескольких потоков, все из которых работают с одним и тем же кодом).
Сказав, что вы, конечно же, можете сделать это выше, путем создания расширения класса потока, который устанавливает его имя в трассировку стека его создания, а затем использовать его с вашими реализациями Runnable вместо стандартный класс java Thread (см. ниже), но в дополнение к трассировке стека может быть больше контекстной информации, которая была бы полезной в имени потока для отладки (ссылка на одну из многих очередей или сокетов, которые она могла бы обрабатывать, например, в этом случае вы можете предпочесть расширить Thread специально для этого случая, чтобы вы могли заставить компилятор заставить вас (или других пользователей, использующих ваши библиотеки) передавать определенную информацию (например, указанная очередь / сокет) для использования в имени).
Вот пример общего потока с трассировкой стека вызовов как его имя:
public class DebuggableThread extends Thread {
private static String getStackTrace(String name) {
Throwable t= new Throwable("DebuggableThread-"+name);
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(os);
t.printStackTrace(ps);
return os.toString();
}
public DebuggableThread(String name) {
super(getStackTrace(name));
}
public static void main(String[] args) throws Exception {
System.out.println(new Thread());
System.out.println(new DebuggableThread("MainTest"));
}
}
и вот образец выходного файла, сравнивающий два имени:
Thread[Thread-1,5,main]
Thread[java.lang.Throwable: DebuggableThread-MainTest
at DebuggableThread.getStackTrace(DebuggableThread.java:6)
at DebuggableThread.<init>(DebuggableThread.java:14)
at DebuggableThread.main(DebuggableThread.java:19)
,5,main]
Runnable
, действительно может управлять именем потока, поскольку поток, выполняющий код, по определению имеет текущий поток (и любой код, который проходит проверки безопасности i>, имеет контроль над именами потоков). Учитывая, что вы посвящаете половину своего сообщения «omg, как насчет имен нитей!», Это похоже на нечто вроде большой сделки.
– cHao
2 November 2012 в 16:02
Я бы сказал, что есть третий способ:
public class Something {
public void justAnotherMethod() { ... }
}
new Thread(new Runnable() {
public void run() {
instanceOfSomething.justAnotherMethod();
}
}).start();
Возможно, это немного повлияло на мое недавнее интенсивное использование Javascript и Actionscript 3, но таким образом ваш класс не должен реализовывать довольно смутный интерфейс, такой как Runnable
.
Если я не ошибаюсь, он более или менее похож на
В чем разница между интерфейсом и абстрактным классом?
extends устанавливает " Является отношением & amp; реализует Runnable :
Предпочитаете « extends Thread ":
Как правило, вам не нужно переопределять поведение Thread. Таким образом, внедрение Runnable является предпочтительным в большинстве случаев.
В другой заметке использование расширенного API ExecutorService
или ThreadPoolExecutorService
обеспечивает большую гибкость и контроль.
Взгляните на этот вопрос SE:
Можем ли мы повторно посетить основную причину, по которой мы хотели, чтобы наш класс вел себя как Thread
? Нет никакой причины, мы просто хотели выполнить задачу, скорее всего, в асинхронном режиме, что точно означает, что выполнение задачи должно входить из нашего основного потока и основного потока, если заканчивается раньше, может или не может ждать для разветвленного пути (задачи).
Если это целая цель, то где я вижу потребность в специализированном потоке. Это может быть достигнуто путем сбора RAW-потока из пула потоков в системе и назначения его нашей задачи (может быть экземпляром нашего класса), и это все.
Итак, будем подчиняться концепции ООП и писать класс типа, который нам нужен. Есть много способов сделать что-то, делайте это правильно.
Нам нужна задача, поэтому напишите определение задачи, которое можно запустить в потоке. Поэтому используйте Runnable.
Всегда помните, что implements
специально используется для придания поведения, а extends
используется для передачи функции / свойства.
Мы не хотим, чтобы свойство потока , вместо этого мы хотим, чтобы наш класс работал как задача, которая может быть запущена.
Это S из SOLID : Единая ответственность.
thread олицетворяет текущий контекст (как в контексте выполнения: стек стека, идентификатор потока и т. д.) асинхронного выполнения части код. То, что кусок кода в идеале должен быть одной и той же реализацией, будь то синхронный или асинхронный .
Если вы объедините их вместе в одна реализация, вы даете результирующему объекту две несвязанные причины изменения:
Если используемый вами язык поддерживает частичные классы или множественное наследование, вы можете разделить каждую причину в своем собственном суперклассе, но это сводится к тому же, что и составление двух объектов, поскольку их наборы функций не перекрываются. Это для теории.
На практике, вообще говоря, программе не нужно выполнять больше сложностей, чем необходимо. Если у вас есть один поток, работающий над конкретной задачей, без изменения этой задачи, вероятно, нет смысла делать задачи отдельными классами, а ваш код будет проще.
В контексте Java , поскольку средство уже существует, возможно, легче начать прямо с самостоятельных классов Runnable
и передать свои экземпляры в Thread
(или Executor
) экземпляров. Как только использовал для этого шаблона, его труднее использовать (или даже читать), чем простой исполняемый поток.
Если вы хотите реализовать или расширить любой другой класс, тогда интерфейс Runnable
наиболее предпочтителен, если вы не хотите, чтобы какой-либо другой класс расширялся или реализовывался, тогда предпочтительнее Thread
класс
. наиболее распространенная разница -
[/g1]
Когда вы extends Thread
класс, после этого вы не можете продлить какой-либо другой класс, который вам нужен. (Как вы знаете, Java не позволяет наследовать более одного класса).
Когда вы implements Runnable
, вы можете сохранить пространство для своего класса для расширения любого другого класса в будущем или сейчас.
Предоставлено из javarevisited.blogspot.com
Эти были заметной разницей между Thread и Runnable в Java, если вы знаете какие-либо другие отличия от Thread vs Runnable, чем поделиться ими с помощью комментариев. Я лично использую Runnable over Thread для этого сценария и рекомендую использовать интерфейс Runnable или Callable на основе вашего требования.
Однако существенная разница.
Когда вы extends Thread
класс, каждый из ваших потоков создает уникальный объект и связывается с ним. Когда вы implements Runnable
, он разделяет один и тот же объект на несколько потоков.
Мораль истории:
Наследовать, только если вы хотите переопределить какое-либо поведение.
Или, скорее, его следует читать как:
Наследовать меньше, интерфейс больше.
run()
.
– Warren Dew
7 June 2016 в 04:01
java.lang.Thread
, переопределив метод run()
. В этом случае вам нужно переопределить метод start()
, я думаю. Обычно вы просто повторно используете поведение java.lang.Thread
, вводя ваш блок выполнения в метод run()
.
– sura2k
6 July 2016 в 09:28
Разделение класса Thread из реализации Runnable также позволяет избежать возможных проблем синхронизации между потоком и методом run (). Отдельный Runnable обычно дает большую гибкость в том, как ссылающийся и исполняемый код ссылается и выполняется.
Java не поддерживает множественную наследование, поэтому, если вы расширяете класс Thread, тогда никакой другой класс не будет расширен.
Например: если вы создаете апплет, то он должен расширять класс Applet, поэтому здесь единственный способ создать поток - реализовать интерфейс Runnable
Добавление моих двух центов здесь - всегда по возможности используйте implements Runnable
. Ниже приведены два оговорки о том, почему вы не должны использовать extends Thread
s
Thread
должен быть сделан final
. По крайней мере, такие методы, как thread.getId()
. См. это обсуждение для ошибки, связанной с расширением Thread
s. См. http://pastebin.com/BjKNNs2G .
public class WaitPuzzle {
public static void main(String[] args) throws InterruptedException {
DoNothing doNothing = new DoNothing();
new WaitForever(doNothing).start();
new WaitForever(doNothing).start();
new WaitForever(doNothing).start();
Thread.sleep(100);
doNothing.start();
while(true) {
Thread.sleep(10);
}
}
static class WaitForever extends Thread {
private DoNothing doNothing;
public WaitForever(DoNothing doNothing) {
this.doNothing = doNothing;
}
@Override
public void run() {
synchronized (doNothing) {
try {
doNothing.wait(); // will wait forever here as nobody notifies here
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Unreachable Code");
}
}
}
static class DoNothing extends Thread {
@Override
public void run() {
System.out.println("Do Nothing ");
}
}
}
Ну так много хороших ответов, я хочу добавить еще об этом. Это поможет понять Extending v/s Implementing Thread
.Extends очень тесно связывает два файла класса и может привести к довольно сложному решению кода.
Оба подхода выполняют одну и ту же работу, но были некоторые различия. Наиболее распространенным отличием является
Однако, одна существенная разница между реализацией Runnable и продолжением Thread заключается в том, что by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.
Следующий пример помогает вам более четко понять
//Implement Runnable Interface...
class ImplementsRunnable implements Runnable {
private int counter = 0;
public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
}
//Extend Thread class...
class ExtendsThread extends Thread {
private int counter = 0;
public void run() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
}
//Use above classes here in main to understand the differences more clearly...
public class ThreadVsRunnable {
public static void main(String args[]) throws Exception {
// Multiple threads share the same object.
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
Thread t3 = new Thread(rc);
t3.start();
// Creating new instance for every thread access.
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // Waiting for 1 second before starting next thread
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
}
Вывод вышеуказанной программы.
ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
В интерфейсе интерфейса Runnable создается только один экземпляр класса, и он был разделен разными потоками. Таким образом, значение счетчика увеличивается для каждого доступа к потоку.
В то время как подход класса Thread, вы должны создать отдельный экземпляр для каждого потока. Следовательно, для каждого экземпляра класса выделяется различная память, и каждый имеет отдельный счетчик, значение остается таким же, что означает, что приращение не произойдет, потому что ни одна из ссылок на объекты не является такой же.
Когда использовать Runnable? Используйте интерфейс Runnable, если вы хотите получить доступ к одному и тому же ресурсу из группы потоков. Избегайте использования класса Thread здесь, потому что создание нескольких объектов потребляет больше памяти, и это становится большой служебной нагрузкой.
Класс, который реализует Runnable, не является нитью и просто классом. Чтобы Runnable стал потоком, вам нужно создать экземпляр Thread и передать себя в качестве цели.
В большинстве случаев интерфейс Runnable должен использоваться, если вы только планируете переопределить run()
и других методов Thread. Это важно, потому что классы не должны подклассифицироваться, если программист не намерен модифицировать или улучшать фундаментальное поведение класса.
Когда необходимо расширить суперкласс, реализация интерфейса Runnable более подходит, чем использование класс Thread. Потому что мы можем расширять другой класс при реализации интерфейса Runnable для создания потока.
Надеюсь, это поможет!
ExtendsThread et = new ExtendsThread();
Thread tc1 = new Thread(et);
tc1.start();
Thread.sleep(1000);
Thread tc2 = new Thread(et);
tc2.start();
Thread.sleep(1000);
Thread tc3 = new Thread(et);
tc3.start();
Насколько яснее?
– zEro
10 June 2013 в 07:31
Thread
приращение, также является ли утверждение by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance
неправильным? Если нет, то что такое случай, демонстрирующий это?
– Evil Washing Machine
9 February 2015 в 12:23
+ " hashcode: " + this.hashCode()
– zEro
18 May 2015 в 20:07
Да. Если вы вызываете вызов ThreadA, тогда не нужно вызывать метод start, а метод run - это вызов после вызова класса ThreadA. Но если использовать ThreadB-вызов, тогда необходимо создать начальный поток для метода вызова. Если у вас есть дополнительная помощь, ответьте мне.
Runnable, потому что:
Даже если вам не нужно какое-либо из этого сейчас, вы можете в будущем. Поскольку нет преимущества для переопределения Thread, Runnable - лучшее решение.
Одна из причин, по которой вам нужно реализовать интерфейс, а не расширять базовый класс, заключается в том, что вы уже расширяете какой-либо другой класс. Вы можете расширить только один класс, но вы можете реализовать любое количество интерфейсов.
Если вы расширяете Thread, вы в основном предотвращаете выполнение вашей логики любым другим потоком, чем «это». Если вы хотите, чтобы поток выполнял вашу логику, лучше всего реализовать Runnable.
Я не эксперт, но могу придумать одну из причин для внедрения Runnable вместо продолжения Thread: Java поддерживает только одно наследование, поэтому вы можете расширить только один класс.
Изменить: это изначально сказал: «Для реализации интерфейса требуется меньше ресурсов». также, но вам нужно создать новый экземпляр Thread любым способом, так что это было неправильно.
tl; dr: реализует Runnable лучше. Тем не менее, оговорка важна
. В общем, я бы рекомендовал использовать что-то вроде Runnable
, а не Thread
, потому что это позволяет вам поддерживать вашу работу только в сочетании с вашим выбором параллелизма. Например, если вы используете Runnable
и позже решили, что на самом деле этого не требуется Thread
, вы можете просто вызвать threadA.run ().
Предостережение: здесь, Я категорически отвергаю использование необработанных потоков. Я предпочитаю использовать Callables и FutureTasks (Из javadoc: «Адаптивное асинхронное вычисление»). Интеграция тайм-аутов, правильная отмена и объединение потоков современной поддержки параллелизма для меня гораздо более полезны, чем груды необработанных потоков.
Последующие действия: существует конструктор FutureTask
, который позволяет использовать Runnables (если это то, что вам больше всего нравится), и по-прежнему пользоваться преимуществами современных инструментов параллелизма. Процитировать javadoc:
Если вам не нужен конкретный результат, подумайте об использовании конструкций формы:
Future<?> f = new FutureTask<Object>(runnable, null)
Итак, если мы заменим их runnable
на ваш threadA
, мы получаем следующее:
new FutureTask<Object>(threadA, null)
Другим вариантом, который позволяет вам оставаться ближе к Runnables, является ThreadPoolExecutor . Вы можете использовать метод execute для передачи в Runnable для выполнения «данной задачи в будущем».
Если вы хотите попробовать использовать пул потоков, вышеописанный фрагмент кода будет выглядеть примерно следующим образом (с использованием фабричного метода Executors.newCachedThreadPool () ):
ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());
es
будет лучше как статическое (или введенное) поле, так что он будет создан только один раз.
– artbristol
19 November 2012 в 13:27
FutureTask
напрямую, как правило, не то, что вы хотите сделать. ExecutorService
s создаст для вас соответствующий Future
, если вы submit
a Runnable
/ Callable
к ним. Аналогично для ScheduledExecutorService
s и ScheduledFuture
, когда вы schedule
a Runnable
/ Callable
.
– Powerlord
28 April 2015 в 13:44
Разница между Thread и runnable. Если мы создаем Thread с использованием класса Thread, тогда количество потоков равно количеству созданного нами объекта. Если мы создаем поток, реализуя интерфейс runnable, мы можем использовать один объект для создания нескольких потоков. Один объект разделяется несколькими Thread.So он будет потреблять меньше памяти
. Поэтому в зависимости от требования, если наш данные не являются сенситивными. Таким образом, он может быть разделен между несколькими Thread, которые мы можем использовать интерфейс Runnable.
На самом деле, нецелесообразно сравнивать Runnable
и Thread
друг с другом.
У этих двух есть зависимость и взаимосвязь в многопоточности, как Wheel and Engine
отношение автомобиля.
Я бы сказал, есть только один способ многопоточности с двумя шаги. Позвольте мне высказать свою мысль.
Runnable: при реализации interface Runnable
это означает, что вы создаете что-то, что run able
в другом потоке. Теперь создание чего-то, что может работать внутри потока (runnable внутри потока), не означает создание Thread. Таким образом, класс MyRunnable
- не что иное, как обычный класс с методом void run
. И это объекты будут обычными объектами только с методом run
, который будет нормально выполняться при вызове. (если мы не передадим объект в потоке).
Тема: class Thread
, я бы сказал, очень специальный класс с возможностью запуска нового потока, который фактически позволяет многопоточность через start()
метод.
Почему не разумно сравнивать? Потому что нам нужны оба для многопоточности.
Для многопоточности нам нужны две вещи:
Так что технически и теоретически оба из них необходимы, чтобы начать поток, один запустится, и один сделает
Вот почему вы не можете запустить нить с MyRunnable
, вам нужно передать ее в экземпляр Thread
.
Но можно создать и запустить поток только с помощью class Thread
, потому что класс Thread
реализует Runnable
, поэтому мы все знаем, что Thread
также является Runnable
внутри.
Наконец Thread
] и Runnable
дополняют друг друга для многопоточности, не являющейся конкурентом или заменой.
ThreadA
больше не имеет смысла
– idelvall
22 March 2016 в 17:51
Thread
класс, вы потеряли свой шанс и не можете расширять или наследовать другой класс на Java. Thread
, чем используем интерфейс Runnable
. Интерфейс Runnable
представляет собой Task
, который может быть выполнен либо обычным Thread
, либо Executors
или любые другие средства. Таким образом, логическое разделение Task
как Runnable
, чем Thread
, является хорошим конструктивным решением. Runnable
означает, что мы можем повторно использовать задачу, а также иметь возможность выполнять ее с разных средств. Поскольку вы не можете перезапустить Thread
после его завершения, снова Runnable
vs Thread
для задачи, Runnable
является победителем. Executors
принимает Runnable
] как Task
, и у них есть рабочий поток, который выполняет эту задачу. Thread
- дополнительные накладные расходы только для представления функции Task
, которая может быть легко выполнена с помощью Runnable
. Это обсуждается в учебнике Oracle Определение и запуск потока :
Какую из этих идиом вы должны использовать? Первая идиома, которая использует объект Runnable, является более общей, поскольку объект Runnable может подклассифицировать класс, отличный от Thread. Вторая идиома проста в использовании в простых приложениях, но ограничена тем, что ваш класс задачи должен быть потомком Thread. В этом уроке основное внимание уделяется первому подходу, который отделяет задачу Runnable от объекта Thread, выполняющего задачу. Этот подход не только более гибкий, но применим к API-интерфейсам управления потоками высокого уровня, рассмотренным позже.
Другими словами, реализация
Runnable
будет работать в сценариях, где ваш класс расширяется класс, отличный отThread
. Java не поддерживает множественное наследование. Кроме того, расширениеThread
не будет возможно при использовании некоторых высокоуровневых API управления потоками. Единственный сценарий, когда расширениеThread
предпочтительнее, - это небольшое приложение, которое в будущем не будет обновляться. Практически лучше реализоватьRunnable
, поскольку он более гибкий по мере роста вашего проекта. Изменение дизайна не окажет большого влияния, поскольку вы можете реализовать множество интерфейсов в java, но только расширить один класс.
Создание экземпляра интерфейса дает более четкое разделение между вашим кодом и реализацией потоков, поэтому я предпочел бы реализовать Runnable в этом случае.
Я считаю, что наиболее полезно использовать Runnable для всех упомянутых причин, но иногда мне нравится продлить Thread, поэтому я могу создать свой собственный метод остановки потока и вызвать его непосредственно на созданном мной потоке.
Одна разница между реализацией Runnable и продолжением Thread заключается в том, что путем расширения Thread каждый из ваших потоков имеет уникальный объект, связанный с ним, тогда как при реализации Runnable многие потоки могут совместно использовать один и тот же экземпляр объекта.
A класс, который реализует Runnable, не является потоком и просто классом. Чтобы Runnable выполнялся потоком, вам нужно создать экземпляр Thread и передать экземпляр Runnable в качестве цели.
В большинстве случаев интерфейс Runnable должен использоваться, если вы планируете только планировать для переопределения метода run () и других методов Thread. Это важно, потому что классы не должны подклассифицироваться, если программист не намерен модифицировать или улучшать фундаментальное поведение класса.
Когда необходимо расширить суперкласс, реализация интерфейса Runnable более подходит, чем использование класс Thread. Потому что мы можем расширить другой класс, внедряя интерфейс Runnable для создания потока. Но если мы просто расширим класс Thread, мы не сможем наследовать ни от какого другого класса.
, если вы используете runnable, вы можете сохранить пространство, чтобы перейти к любому другому классу.
Поскольку это очень популярная тема, и хорошие ответы распространяются повсюду и рассматриваются в большой степени, я счел оправданным составить хорошие ответы от других в более сжатые формы, так что новички имеют простой обзор upfront:
if (numberCores > 4) myExecutor.excute(myRunnable); else myRunnable.run()
– user949300 6 March 2013 в 21:30extends Thread
, и если вам не нужна потоковая передача, почему бы вы даже реализоватьRunnable
... – m0skit0 23 April 2013 в 09:15