11 ответов:
см. объяснение здесь.
вызываемый интерфейс похож на Выполнимое, в которые оба предназначены для классов, экземпляры которых являются потенциально оформленную на другого нитка. A Runnable, однако, не делает возвращает результат и не может бросить отмеченное исключение.
каковы различия в приложениях
RunnableиCallable. Является ли разница только с возвращаемым параметром, присутствующим вCallable?в принципе, да. Смотрите ответы на этот вопрос. А то javadoc для
Callable.какая необходимость иметь оба, если
Callableможет сделать все этоRunnableделает?потому что
Runnableинтерфейс не может сделать все, чтоCallableделает!
Runnableсуществует с Java 1.0, ноCallableбыл введен только в Java 1.5 ... для обработки прецедентов, которыеRunnableне поддерживает. Теоретически, команда Java могла бы изменить подписьRunnable.run()метод, но это нарушило бы двоичную совместимость с кодом pre-1.5, требуя перекодирования при переносе старого кода Java на более новые JVMs. Это большое НЕТ-НЕТ. Java стремится быть обратно совместимым ... и это была одна из самых больших точек продаж Java для бизнес-вычислений.и, очевидно, есть случаи использования, когда задача не нужно чтобы вернуть результат или создать проверенное исключение. Для этих случаев использования, используя
Runnableболее кратким, чем при использованииCallable<Void>и возвращение соска (null) значениеcall()метод.
- A
Callableнеобходимо реализоватьcall()метод в то время какRunnableнеобходимо реализоватьrun()метод.- A
Callableможет возвращать значение, ноRunnableне может.- A
Callableможет бросить проверенное исключение, ноRunnableне может.A
Callableможно использовать сExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)методы, но aRunnableне может быть.public interface Runnable { void run(); } public interface Callable<V> { V call() throws Exception; }
Я нашел это в другом блоге, которая может объяснить это немного больше различия:
хотя оба интерфейса реализованы классами, которые хотят выполнить в другом потоке выполнения, но есть несколько различий между двумя интерфейсами, которые являются:
- A
Callable<V>экземпляр возвращает результат типаV, тогда как aRunnableэкземпляра нет.- A
Callable<V>экземпляр может бросить проверено исключения, тогда какRunnableэкземпляр не можетдизайнеры Java почувствовали необходимость расширения возможностей
Runnableинтерфейс, но они не хотели влиять на использованиеRunnableинтерфейс и, вероятно, именно по этой причине они пошли на наличие отдельного интерфейса с именемCallableв Java 1.5, чем изменение уже существующегоRunnable.
давайте посмотрим, где можно было бы использовать Runnable и Callable.
Runnable и Callable оба работают в другом потоке, чем вызывающий поток. Но Callable может возвращать значение, а Runnable-нет. Так где же это действительно применимо.
Runnable : если у вас есть огонь и забыть задачу, то используйте Runnable. Поместите свой код внутри Runnable и когда вызывается метод run (), вы можете выполнить свою задачу. Вызывающий поток действительно не волнует, когда вы выполняйте свою задачу.
вызвать : если вы пытаетесь получить значение из задачи, то используйте Callable. Теперь callable сам по себе не будет выполнять эту работу. Вам понадобится будущее, которое вы обернете вокруг своего вызываемого и получите свои ценности в будущем.получить.)( Здесь вызывающий поток будет заблокирован до тех пор, пока будущее не вернется с результатами, которые, в свою очередь, ждут выполнения метода Callable call ().
Так что подумайте об интерфейсе к целевому классу, где у вас есть определены как выполняемые, так и вызываемые обернутые методы. Вызывающий класс будет случайным образом вызывать ваши методы интерфейса, не зная, какой из них можно запустить и какой можно вызвать. Выполняемые методы будут выполняться асинхронно, пока не будет вызван вызываемый метод. Здесь поток вызывающего класса будет заблокирован, так как вы извлекаете значения из своего целевого класса.
Примечание: внутри вашего целевого класса вы можете совершать вызовы вызываемых и запускаемых на одном исполнителе потока, что делает этот механизм аналогично очереди последовательной отправки. Таким образом, пока вызывающий вызывает ваши выполняемые обернутые методы, вызывающий поток будет выполняться очень быстро без блокировки. Как только он вызывает вызываемый обернутый в будущий метод, он должен будет блокировать до тех пор, пока не будут выполнены все остальные элементы очереди. Только тогда метод вернется со значениями. Это механизм синхронизации.
Callableинтерфейс объявляетcall()метод и вам нужно предоставить дженерики, поскольку тип вызова объекта() должен возвращать -public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
RunnableС другой стороны интерфейс, который объявляетrun()метод, который вызывается при создании потока с runnable и вызовите start () на нем. Вы также можете напрямую вызвать run (), но это просто выполняет метод run () - это тот же поток.public interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }подводя итог несколько заметных различий
- A
Runnableобъект не возвращает результат, тогда как A только в Java 1.5.несколько сходств включают
- экземпляры классов, реализующих запускаемые или вызываемые интерфейсы потенциально выполняется другим потоком.
- экземпляр как вызываемых, так и запускаемых интерфейсов может быть выполнен ExecutorService с помощью метода submit ().
- оба являются функциональными интерфейсами и могут использоваться в лямбда-выражениях начиная с Java8.
методы в интерфейсе ExecutorService являются
<T> Future<T> submit(Callable<T> task); Future<?> submit(Runnable task); <T> Future<T> submit(Runnable task, T result);
назначение этих интерфейсов из документации oracle:
Runnable интерфейс должен быть реализован любым классом, экземпляры которого предназначены, чтобы быть выполненными
Thread. Класс должен определить метод без аргументов с именемrun.вызвать: задача, которая возвращает результат и может бросить исключение. Разработчики определяют один метод без аргументов Call. Элемент
Callableинтерфейс похож наRunnable, в том, что оба предназначены для классов, экземпляры которых потенциально выполняются другим потоком. АRunnable, однако, не возвращает результат и не может вызвать проверенное исключение.другие отличия:
вы можете пройти
Runnableсоздать Thread. Но вы не можете создать новый поток, передаваяCallableв качестве параметра. Вы можете передать вызываемый только наExecutorServiceэкземпляры.public class HelloRunnable implements Runnable { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); } }использовать
Runnableдля огня и забыть звонки. ИспользуйтеCallableдля проверки результата.
Callableможно передать в invokeAll метод в отличие отRunnable. МетодыinvokeAnyиinvokeAllвыполните наиболее часто используемые формы массового выполнения, выполнив набор задач, а затем дождавшись хотя бы одного или всех полныйтривиальная разница : имя метода, который будет реализован =>
run()наRunnableиcall()наCallable.
Как уже упоминалось здесь Callable-это относительно новый интерфейс, и он был введен как часть пакета параллелизма. Как вызываемый, так и запускаемый могут использоваться с исполнителями. Резьба класс (который реализует интерфейс Runnable себя) поддерживает только выполнимое.
вы все еще можете использовать Runnable с исполнителями. Преимущество Callable в том, что вы можете отправить его исполнителю и сразу же получить обратно будущий результат, который будет обновляться по завершении выполнения. То же самое может быть реализовано с помощью Runnable, но в этом случае вы должны управлять результатами самостоятельно. Например, можно создать очередь результатов, которая будет содержать все результаты. Другой поток может ждать в этой очереди и обрабатывать поступающие результаты.
+-------------------------------------+--------------------------------------------------------------------------------------------------+ | Runnable | Callable<T> | +-------------------------------------+--------------------------------------------------------------------------------------------------+ | Introduced in Java 1.0 of java.lang | Introduced in Java 1.5 of java.util.concurrent library | | Runnable cannot be parametrized | Callable is a parametrized type whose type parameter indicates the return type of its run method | | Runnable has run() method | Callable has call() method | | Runnable.run() returns void | Callable.call() returns a value of Type T | | Can not throw Checked Exceptions | Can throw Checked Exceptions | +-------------------------------------+--------------------------------------------------------------------------------------------------+дизайнеры Java почувствовали необходимость расширения возможностей
Runnableинтерфейс, но они не хотели влиять на использованиеRunnableинтерфейс и, вероятно, именно по этой причине они пошли на наличие отдельного интерфейса с именемCallableв Java 1.5, чем изменение уже существующегоRunnableинтерфейс, который был частью Java с Java 1.0. источник
разницы между отзывной и выполнимое, являются следующие:
- Callable вводится в JDK 5.0, но Runnable вводится в JDK 1.0
- Callable имеет метод call (), но Runnable имеет метод run ().
- вызываемый есть вызов метода, который возвращает значение, но выполнимое и запустить метод, который не возвращает никакого значения.
- метод вызова может вызвать проверенное исключение, но метод запуска не может бросить проверенный исключение.
- отзывной использовать представить() метод, чтобы поставить в очередь задач, но выполнимое использовать метод execute (), чтобы поставили в очередь задач.
общий интерфейс Runnable в: Runnable интерфейс должен быть реализован любым классом, экземпляры которого должны выполняться потоком. Класс должен определить метод без аргументов, называемый run. Этот интерфейс предназначен для обеспечения общего протокола для объектов, которые хотят выполнять код, пока они активны. Например, выполнимое реализуется с помощью класса Thread. Быть активным означает, что поток был запущен и еще не остановившийся.
кроме того, Runnable предоставляет средства для класса, чтобы быть активным, не разделяя поток на подклассы. Класс, реализующий Runnable, может выполняться без подкласса Thread путем создания экземпляра Thread и передачи себя в качестве целевого объекта. В большинстве случаев интерфейс Runnable следует использовать, если вы планируете переопределить только метод run () и никакие другие методы потока. Это важно, потому что классы не должны быть подклассами, если программист не намерен изменение или улучшение фундаментального поведения класса.
с: JDK1.0
вызываемый открытый интерфейс:
задача, которая возвращает результат и может бросить исключение. Разработчики определяют один метод без аргументов Call. Вызываемый интерфейс похож на Runnable, поскольку оба они предназначены для классов, экземпляры которых потенциально выполняются другим потоком. Runnable, однако, не возвращает результат и не может бросить проверенное исключение.
класс Executors содержит служебные методы для преобразования из других распространенных форм в вызываемые классы.
с тех пор: JDK 1.5
Comments