Вопрос интерфейса Java - PullRequest
       19

Вопрос интерфейса Java

4 голосов
/ 24 сентября 2010

Я в замешательстве (новичок в Java):

При реализации интерфейса Runnable необходимо переопределить метод run (), чтобы получить возможность выполнения потока. Реализация этого интерфейса делает ваш объект типом Runnable (?). Как функциональность потока «внедряется», просто реализуя интерфейс Runnable? В основном, когда вы создаете экземпляр класса, который реализует Runnable, что происходит, что связано с функциональностью потоков? Я, вероятно, неправильно понимаю некоторую основную концепцию ОО здесь. Спасибо.

Это JVM, которая "знает", чтобы искать работоспособный объект при выполнении thread.start ()?

Ответы [ 7 ]

9 голосов
/ 24 сентября 2010

Когда вы создаете реализацию Runnable, ничто не связывает ваш класс с возможностями потоков JVM.Экземпляр интерфейса Runnable подобен экземпляру любого другого интерфейса, просто другому экземпляру.

Если вы хотите использовать систему потоков JVM, вы должны использовать новый экземпляр Thread class, который будет запускать метод run() вашей реализации Runnable в отдельном потоке.

Вся логика создания нового потока выполняется классом Thread.

4 голосов
/ 24 сентября 2010

Runnable представляет часть работы, которая «может» выполняться в отдельном потоке или нет (вы можете просто вызвать Runnable.run () самостоятельно).

Однако, чтобы вызвать Runnable в отдельном потоке, выполните что-то вроде

Thread thread = new Thread(new MyRunnable());
thread.start(); // MyRunnable will now be invoked in a new thread
2 голосов
/ 24 сентября 2010

Реализация Runnable волшебным образом не заставляет ваш класс работать в потоке. Вместо этого вы можете сделать что-то вроде:

Runnable myRunnable = new MyRunnable(); // MyRunnable implements Runnable
Thread t = new Thread(myRunnable);
t.start();

Теперь ваш код в методе run () myRunnable будет выполняться в отдельном потоке. Я призываю вас просмотреть ExecutorService и Executors в пакете java.util.concurrent. Это объекты, которые будут выполнять то, что вы передаете (Runnable) в потоке. Преимущество использования Executor / ExecutorService заключается в том, что вы можете заранее определить количество потоков, которые вы хотите выделить, и использовать различные стратегии для увеличения / уменьшения или сохранения константы.

Еще одна интересная вещь для новичка: потоки могут быть потоками демона (фон) или не демон (как пользовательский интерфейс). Ваша JVM не умрет, если запущены потоки, не являющиеся демонами. Чтобы объявить Thread как демон, просто вызовите setDaemon (). Вместе с исполнителем вам потребуется предоставить ThreadFactory, в которой вы создадите поток и отметите его как демон.

Надеюсь, это поможет.

2 голосов
/ 24 сентября 2010

Реализация Runnable не запускает новый поток, чтобы начать новый поток, вам нужно создать новый объект Thread и запустить его, и один из наиболее часто используемых конструкторов Thread принимает Runnable в качестве параметра ( Thread (Runnable) ):

Thread t = new Thread(new MyRunnable());
t.start();
2 голосов
/ 24 сентября 2010

Ничего особенного на самом деле не происходит в фоновом режиме.

Реализация интерфейса Runnable гарантирует, что у вашего класса будет метод public void run().

Волшебство действительно происходит, когда вы передаете свой пользовательский класс в Thread.

Thread th = new Thread(new YourCustomRunnable());
th.start();

В приведенном выше коде будет создан новый Thread, а код внутри метода run() будет запущен в другом потоке.

Внутренне поток вызовет ваш пользовательский метод run() и заставит этот код выполняться в отдельном потоке. Технически возможно сделать следующее:

Runnable r = new MyCustomRunnable();
r.run();

В приведенном выше коде r не будет работать в отдельном потоке.

1 голос
/ 24 сентября 2010

В терминах последних определений нет «инъекций» (весна / DI).Runnable ничем не отличается от любого другого интерфейса.Это «контракт», в котором говорится, что ваш класс предоставляет все необходимые методы, вызываемые в интерфейсе.

1 голос
/ 24 сентября 2010

Интерфейс - это своего рода контракт. Реализуя Runnable, вы обещаете, что предоставите все методы, определенные в интерфейсе. Таким образом, любой другой класс, такой как «Thread», который знает о Runnable.run (), может вызвать этот метод для объекта вашего класса. Даже не зная ничего о вашем классе.

Чтобы начать новый поток с вашим кодом, вам нужно написать что-то вроде этого:

 Thread thread = new Thread(new MyRunnable());
 thread.start();

Метод start () выполнит магию операционной системы для генерации потока, а затем вызовет метод run () в контексте этого потока операционной системы для объекта, который вы указали в качестве параметра для конструктора. *

...