Разница между запускаемым и вызываемым интерфейсами в Java



в чем разница между использованием Runnable и Callable интерфейсы при проектировании параллельных потоков в Java, почему бы вам выбрать один над другим?

694   11  

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) методы, но a Runnable не может быть.

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    

Я нашел это в другом блоге, которая может объяснить это немного больше различия:

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

  • A Callable<V> экземпляр возвращает результат типа V, тогда как a Runnable экземпляра нет.
  • 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();
}

подводя итог несколько заметных различий

  1. A Runnable объект не возвращает результат, тогда как A только в Java 1.5.

несколько сходств включают

  1. экземпляры классов, реализующих запускаемые или вызываемые интерфейсы потенциально выполняется другим потоком.
  2. экземпляр как вызываемых, так и запускаемых интерфейсов может быть выполнен ExecutorService с помощью метода submit ().
  3. оба являются функциональными интерфейсами и могут использоваться в лямбда-выражениях начиная с 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, однако, не возвращает результат и не может вызвать проверенное исключение.

другие отличия:

  1. вы можете пройти 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();
        }
    
    }
    
  2. использовать Runnable для огня и забыть звонки. Используйте Callable для проверки результата.

  3. Callable можно передать в invokeAll метод в отличие от Runnable. Методы invokeAny и invokeAll выполните наиболее часто используемые формы массового выполнения, выполнив набор задач, а затем дождавшись хотя бы одного или всех полный

  4. тривиальная разница : имя метода, который будет реализован => 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. источник

разницы между отзывной и выполнимое, являются следующие:

  1. Callable вводится в JDK 5.0, но Runnable вводится в JDK 1.0
  2. Callable имеет метод call (), но Runnable имеет метод run ().
  3. вызываемый есть вызов метода, который возвращает значение, но выполнимое и запустить метод, который не возвращает никакого значения.
  4. метод вызова может вызвать проверенное исключение, но метод запуска не может бросить проверенный исключение.
  5. отзывной использовать представить() метод, чтобы поставить в очередь задач, но выполнимое использовать метод execute (), чтобы поставили в очередь задач.

общий интерфейс Runnable в: Runnable интерфейс должен быть реализован любым классом, экземпляры которого должны выполняться потоком. Класс должен определить метод без аргументов, называемый run. Этот интерфейс предназначен для обеспечения общего протокола для объектов, которые хотят выполнять код, пока они активны. Например, выполнимое реализуется с помощью класса Thread. Быть активным означает, что поток был запущен и еще не остановившийся.

кроме того, Runnable предоставляет средства для класса, чтобы быть активным, не разделяя поток на подклассы. Класс, реализующий Runnable, может выполняться без подкласса Thread путем создания экземпляра Thread и передачи себя в качестве целевого объекта. В большинстве случаев интерфейс Runnable следует использовать, если вы планируете переопределить только метод run () и никакие другие методы потока. Это важно, потому что классы не должны быть подклассами, если программист не намерен изменение или улучшение фундаментального поведения класса.

с: JDK1.0


вызываемый открытый интерфейс:

задача, которая возвращает результат и может бросить исключение. Разработчики определяют один метод без аргументов Call. Вызываемый интерфейс похож на Runnable, поскольку оба они предназначены для классов, экземпляры которых потенциально выполняются другим потоком. Runnable, однако, не возвращает результат и не может бросить проверенное исключение.

класс Executors содержит служебные методы для преобразования из других распространенных форм в вызываемые классы.

с тех пор: JDK 1.5

Comments

    Ничего не найдено.