Thread - ExecuteService

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!

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?

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 !

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

threads !!

[quote=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![/quote]

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.

[quote][quote=entanglement][quote=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![/quote]

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. [/quote]

O que eu queria saber foi explicado aqui:

Bem, eu não sabia disso…

Obrigado.[/quote]

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?

oi,

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

abs

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

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.

É 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?

[quote=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.
    [/quote]
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?

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.

[quote=entanglement][quote]
Executors.newFixedThreadPool(3) irá me criar 3 threads e depois retornar um ExecutorService.
[/quote]

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.

[/quote]

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?