Thread - ExecuteService

12 respostas
ECO2004

Olá, pessoal!

Estou com uma dúvida com relação à interface ExecuteService.

Essa interface possui a declaração de um conjunto de métodos que servem para gerenciar Execute.

O que não entendo é o seguinte.

Quando vou criar um pool de thread, faço:

ExecuteService threadExecutor = Executors.newFixedThreadPool(algumInteiro)

Mas ExecuteService é uma interface. Não entendi essa criação de “objeto” de interface (threadExecutor) e nem essa atribuição!

ExecuteService deriva de Execute. Assim, herda a declaração do método “execute”, usada para rodar as threads.

Para entenderem melhor a minha dúvida, seria normal ao meu ver ExecutorService ser uma classe e assim fazer threadExecutor.execute(Runnable r).

Espero ter sido claro!

12 Respostas

ECO2004

Aí, eu faço:

threadExecutor.execute(Runnable r);

Mas threadExecuter é uma interface, e não uma classe. Assim, possui a declaração dos métodos, não a sua implementação!

Alguém se abilita a me explicar o que acontece?

overkill

Cara o ExecutorService gerencia um pool de theads que executam ao mesmo tempo …

entao quando vc constroi ele diz o tamanho inicial depois é só ir jugando as threads para dentro que ele processa conforme o tamanho do pool …

não entendi a questão de interface !

overkill

O objeto que vc joga para dentro do executoservice deve ser uma thread … pode ser extendido ou usando a interface runnable !

threads !!

E

ECO2004:
Olá, pessoal!

Estou com uma dúvida com relação à interface ExecuteService.

Essa interface possui a declaração de um conjunto de métodos que servem para gerenciar Execute.

O que não entendo é o seguinte.

Quando vou criar um pool de thread, faço:

ExecuteService threadExecutor = Executors.newFixedThreadPool(algumInteiro)

Mas ExecuteService é uma interface. Não entendi essa criação de “objeto” de interface (threadExecutor) e nem essa atribuição!

ExecuteService deriva de Execute. Assim, herda a declaração do método “execute”, usada para rodar as threads.

Para entenderem melhor a minha dúvida, seria normal ao meu ver ExecutorService ser uma classe e assim fazer threadExecutor.execute(Runnable r).

Espero ter sido claro!

Você está tendo um problema de Java, não de threads.

Variáveis não são a mesma coisa que objetos.

Variáveis podem ter um tipo (interface ou classe), e são posições de memória que guardam referências a objetos (mas não os próprios objetos;
Objetos devem ter uma classe, e é a classe que implementa interfaces.

Quando você declara “ExecutorService threadExecutor”, está indicando que você está declarando uma variável (ou seja, um espaço em memória que contém uma referência, cujo tipo é a interface ExecutorService).

Dessa forma, essa variável pode conter uma referência a qualquer objeto que pertença a uma classe que implemente a interface ExecutorService. Por exemplo, poderíamos ter:

ExecutorService threadExecutor = Executors.newFixedThreadPool (...); // este método retorna um objeto da classe ThreadPoolExecutor, que implementa ExecutorService
ExecutorService threadExecutor = Executors.newSingleThreadExecutor(...); // este método retorna um objeto da classe FinalizableDelegatedExecutorService
ExecutorService threadExecutor = Executors.newScheduledThreadPool(...); // este método retorna um objeto da classe ScheduledThreadPoolExecutor

Mas você, usando essa variável, não precisa saber a classe concreta desse objeto, se você só se limitar a chamar os métodos definidos pela interface.

ECO2004

entanglement:
ECO2004:
Olá, pessoal!

Estou com uma dúvida com relação à interface ExecuteService.

Essa interface possui a declaração de um conjunto de métodos que servem para gerenciar Execute.

O que não entendo é o seguinte.

Quando vou criar um pool de thread, faço:

ExecuteService threadExecutor = Executors.newFixedThreadPool(algumInteiro)

Mas ExecuteService é uma interface. Não entendi essa criação de “objeto” de interface (threadExecutor) e nem essa atribuição!

ExecuteService deriva de Execute. Assim, herda a declaração do método “execute”, usada para rodar as threads.

Para entenderem melhor a minha dúvida, seria normal ao meu ver ExecutorService ser uma classe e assim fazer threadExecutor.execute(Runnable r).

Espero ter sido claro!

Você está tendo um problema de Java, não de threads.

Variáveis não são a mesma coisa que objetos.

Variáveis podem ter um tipo (interface ou classe), e são posições de memória que guardam referências a objetos (mas não os próprios objetos;
Objetos devem ter uma classe, e é a classe que implementa interfaces.

Quando você declara “ExecutorService threadExecutor”, está indicando que você está declarando uma variável (ou seja, um espaço em memória que contém uma referência, cujo tipo é a interface ExecutorService).

Dessa forma, essa variável pode conter uma referência a qualquer objeto que pertença a uma classe que implemente a interface ExecutorService. Por exemplo, poderíamos ter:

ExecutorService threadExecutor = Executors.newFixedThreadPool (...); // este método retorna um objeto da classe ThreadPoolExecutor, que implementa ExecutorService
ExecutorService threadExecutor = Executors.newSingleThreadExecutor(...); // este método retorna um objeto da classe FinalizableDelegatedExecutorService
ExecutorService threadExecutor = Executors.newScheduledThreadPool(...); // este método retorna um objeto da classe ScheduledThreadPoolExecutor

Mas você, usando essa variável, não precisa saber a classe concreta desse objeto, se você só se limitar a chamar os métodos definidos pela interface.

O que eu queria saber foi explicado aqui:

Bem, eu não sabia disso…

Obrigado.

Uma vez eu tinha perguntado no GUJ para que servia uma variável do tipo Interface. Responderam, mas outra coisa…

Então quer dizer que eu posso ter uma interface que recebe a referência para qualquer classe que implemente a interface?

Olhando a documentação do Java:

public static ExecutorService newFixedThreadPool(int nThreads)

Verifica-se que o retorno do método newFixedThreadPool é ExecutorService, que é uma interface.

ExecutorService threadExecutor recebe essa referência.

threadExecute.execute(Runnable) //aqui reside a dúvida.

O normal para mim, é uma classe X implementar Execute, mais precisamente, o método execute.

Depois eu usaria esse execute() para executar as threads…

Onde está a implementação de execute? Está em “Executors.newFixedTheadPool(inteiro)”?

Ai threadExecutor receberia uma referência a uma classe que implementa execute, que no caso, é newFixedThreadPool(inteiro) ?

É isso que está acontecendo?

Andre_Fonseca

oi,

Leia este pdf para entender o porque de programar para uma interface

abs

ViniGodoy

Outra referência legal sobre o assunto é essa entrevista com o Erich Gamma, criador do Eclipse e do JUnit e co-autor do livro de Design Patterns:
http://www.artima.com/lejava/articles/designprinciples.html

E

A implementação de execute está nas classes que implementam ExecutorService.
Note que para o programa é completamente indiferente se a variável é uma referência para um objeto da classe ThreadPoolExecutor ou FinalizableDelegatedExecutorService ou ScheduledThreadPoolExecutor ou então outra classe qualquer que implemente ExecutorService.
Basicamente:

  • Seu programa pega a variável threadExecutor e os parãmetros para o método execute.
  • Através do tipo da referência contida em threadExecutor (digamos que seja ThreadPoolExecutor), ele descobre que tem de chamar o método execute da classe ThreadPoolExecutor, não o método execute da classe FinalizableDelegatedExecutorService ou da ScheduledThreadPoolExecutor.
    Isso em Java é o normal e esperado.
ECO2004

É bem bacana o que você acaba de me explicar…

ExecutorService threadExecutor é uma variável de uma interface que recebe a referência para uma classe que implementa ExecutorService.

Eu não sei muito ainda sobre “chamar os métodos a partir de sua interface”, ao invés de suas implementações.

Onde estudo mais isso?

ECO2004

entanglement:
A implementação de execute está nas classes que implementam ExecutorService.
Note que para o programa é completamente indiferente se a variável é uma referência para um objeto da classe ThreadPoolExecutor ou FinalizableDelegatedExecutorService ou ScheduledThreadPoolExecutor ou então outra classe qualquer que implemente ExecutorService.
Basicamente:

  • Seu programa pega a variável threadExecutor e os parãmetros para o método execute.
  • Através do tipo da referência contida em threadExecutor (digamos que seja ThreadPoolExecutor), ele descobre que tem de chamar o método execute da classe ThreadPoolExecutor, não o método execute da classe FinalizableDelegatedExecutorService ou da ScheduledThreadPoolExecutor.
    Isso em Java é o normal e esperado.
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);

Bem, Executors.newFixedThreadPool(3) irá me criar 3 threads e depois retornar um ExecutorService.

Quando faço

threadExecutor.execute(task1)

por exemplo, qual execute ele chama, já que não houve referência para qualquer classe que implemente ExecuteService?

E

Mais rigorosamente, Executors.newFixedThreadPool irá retornar-lhe um objeto de uma classe que implementa ExecutorService.
Casualmente (olhando a implementação, ou então imprimindo o nome da classe desse objeto usando System.out.println (threadExecutor.getClass().getName()) você sabe que é um ThreadPoolExecutor, mas poderia ser qualquer outra coisa que pertencesse a uma classe que implementasse ExecutorService.

Qual é o execute que ele chama? Só de olhar o programa você não sabe. O Java faz o seguinte (simplificadamente: )

a) Ele verifica qual o tipo da classe à qual pertence o objeto que está sendo apontado por essa referência, contida na variável threadExecutor;

b) Uma vez determinando o tipo da classe, ele chama o execute correto.

ECO2004

entanglement:

Executors.newFixedThreadPool(3) irá me criar 3 threads e depois retornar um ExecutorService.

Mais rigorosamente, Executors.newFixedThreadPool irá retornar-lhe um objeto de uma classe que implementa ExecutorService.
Casualmente (olhando a implementação, ou então imprimindo o nome da classe desse objeto usando System.out.println (threadExecutor.getClass().getName()) você sabe que é um ThreadPoolExecutor, mas poderia ser qualquer outra coisa que pertencesse a uma classe que implementasse ExecutorService.

Qual é o execute que ele chama? Só de olhar o programa você não sabe. O Java faz o seguinte (simplificadamente: )

a) Ele verifica qual o tipo da classe à qual pertence o objeto que está sendo apontado por essa referência, contida na variável threadExecutor;

b) Uma vez determinando o tipo da classe, ele chama o execute correto.

Então, só olhando para

ExecutorService threadExecutor = Executors.newFixedThreadPool(3);

não dá para saber qual classe está implementando ExecutorService? A escolha da classe (AbstractExecutorService, ScheduledThreadPoolExecutor ou ThreadPoolExecutor) é feita dinamicamente?

Na documentação da classe Executors, vejo que o retorno do método

newFixedThreadPool(int)

é ExecutorService. Esse ExecutorService no retorno signica qualquer objeto que o implemente, ou seja, AbstractExecutorService, ScheduledThreadPoolExecutor ou ThreadPoolExecutor, certo?

Criado 14 de julho de 2011
Ultima resposta 14 de jul. de 2011
Respostas 12
Participantes 5