2015-07-17 4 views
-3

Что произойдет, если поток был выполнен одновременно один раз более одного раза. Допустим, у меня есть нить, какЧто произойдет, если Runnable выполняется несколько раз в ExecutorService

private Runnable mySampleThread() { 
    return new Runnable() { 
     @Override 
     public void run() { 
     //something is going on here. 

     } 
    }; 
} 

И я создал ExecutorService с фиксированным пула потоков 10. Что произойдет, если я исполню mySampleThread 10 раз в этом ExecutorService. Что-то, как показано ниже,

ExecutorService mySampleExecutor = Executors.newFixedThreadPool(10); 
while (i <= 10) { 
    mySampleExecutor.execute(mySampleThread); 
    i++; 
} 
+2

Вы попробовали? что происходит? сначала попробуйте его –

+1

'Runnable' не' Thread'. Это простой Java-объект с одним методом. Все, что произошло, это метод, который был выполнен не один раз. –

+2

«Что произойдет, если ..» несколько шире. Сузить.Упомяните, что вы ожидаете, что вы не делаете и что на самом деле происходит (сначала запустив свой код). Кажется, вы намекаете на воздействие нескольких потоков, порождаемых из одного и того же объекта Runnable. – SuperSaiyan

ответ

0

Там не будет никаких различий в mySampleExecutor.execute(mySampleThread);, mySampleThread метод возвращает новый Runnable object. каждый поток будет иметь свой собственный Frames

3

Ответ очень прост. Исполнитель выполнит Runnable объект (это не объект Thread), как описано в документации Interface Executor

Выполняет заданную команду в какой-то момент в будущем. Команда может выполняться в новом потоке, в объединенном потоке или в вызывающем потоке по усмотрению реализации Executor.

В основном, Палач подберут одну нить из его внутренний бассейн (ThreadPoolExecutor), назначить работоспособным для него выполнить run() метод.

1

Прежде всего, разработайте свою проблему или запрос.

Тем не менее, при условии, что вы вызываете метод «mySampleThread()» без пропущенных скобок. Этот метод на самом деле возвращает новый объект Runnable каждый раз, поэтому вы передаете новому runnable все 10 раз исполнителю. И это означает, что вы отправляете 10 различных заданий исполнителю. Поэтому, если исполнитель создает различный поток для каждой задачи (которая зависит от ее реализации), то все, что вы делаете внутри внутри run(), будет выполняться 10 раз в 10 разных потоках.

И как описано в других ответах, исполняемый объект, передаваемый исполнителю, не является потоком.

Надеюсь, он уточнит.

Кстати, вы можете попробовать запустить программу.

0

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

Что стоит упомянуть, и я лично использовал это довольно много раз - это один из способов обмена данными между несколькими потоками, так как все эти потоки разделяют Runnable, который использовался для создания. На данный момент возникают проблемы с синхронизацией, но это уже другая история.

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

import java.util.concurrent.ExecutorService; 

class MyThread implements Runnable { 
    public int counter = 0; 

    @Override 
    public void run() { 
     for (int i = 0; i < 10000; i++) { 
      counter++; 
     } 
    } 
} 

class MySynchronizedThread implements Runnable { 
    public int counter = 0; 

    @Override 
    public void run() { 
     for (int i = 0; i < 10000; i++) { 
      synchronized (this) { 
       counter++; 
      } 
     } 
    } 
} 

public class RunnableTest { 

    public static void main(String[] args) throws InterruptedException { 

     MyThread runnableObject = new MyThread(); 
     ExecutorService ex = Executors.newFixedThreadPool(5); 
     for (int i = 0; i < 5; i++) { 
      ex.execute(runnableObject); 
     } 


     ex.shutdown(); 
     ex.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 

     System.out 
       .println("Without synchronization: " + runnableObject.counter); 

     MyThread runnableSynchronizedObject = new MyThread(); 
     ExecutorService ex2 = Executors.newFixedThreadPool(5); 
     for (int i = 0; i < 5; i++) { 
      ex2.execute(runnableSynchronizedObject); 
     } 

     ex2.shutdown(); 
     ex2.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 
     System.out.println("Without synchronization: " 
       + runnableSynchronizedObject.counter); 

    } 
} 
+0

_ будет столько новых потоков, сколько количество вызовов. Нет. Весь смысл использования службы-исполнителя состоит в том, чтобы _not_ создать новый поток для каждой новой задачи. –

+0

@jameslarge я не думаю, что это ** всего ** точка. Также это утверждение верно как для примера OPs, так и для моего, так что да, будет столько потоков, сколько исполнений. – zubergu

+0

@zubergu Ваш пример действительно объясняет синхронизацию, однако, я не вижу в этом никакого отношения к вопросу. Вы передаете один и тот же объект исполнителю, и вам нужно заботиться о параллелизме. –

Смежные вопросы