Pessoal eu gostaria que vocês me ajudassem no código abaixo…
1. class ThreadA {
2. public static void main(String [] args) {
3. ThreadB b = new ThreadB();
4. b.start();
5.
6. synchronized(b) {
7. try {
8. System.out.println("Waiting for b to comple
9. b.wait();
10. } catch (InterruptedException e) {}
11. System.out.println("Total is: " + b.total);
12. }
13. }
14. }
15.
16. class ThreadB extends Thread {
17. int total;
18.
19. public void run() {
20. synchronized(this) {
21. for(int i=0;i<100;i++) {
22. total += i;
23. }
24. notify();
25. }
26. }
27. }
PEssoal minha duvida é a seguinte :
Na linha 4 quando executa b.start(), está criando uma pilha, e um thread de executação.
Agora minha dúvida: não teria que executar o método run() direto ou não é nada garantido ? Pois eu rodei aqui no meu JVM primeiro ele entra no bloco sincronizado da linha 6. Eu pensava que primeiro ele iria chamar o metodo run() depois iria entrar na linha 6… :roll:
Gostaria que alguem me ajudasse com esse código não entendi muito bem seu fluxo.
OBSERVAÇÃO : TRECHO DE CóDIGO TIRADO DO LIVRO DA K&B.
Putz, você queria a resposta em menos de 2 horas? :mrgreen:
Não, não é nada garantido. Se rodar de novo, talvez ele chame o run() antes.
E ele pode rodar o run(), voltar ao main(), voltar ao run()… ou seja, pode ficar alternando as threads.
E é pra isso que servem as threads. Se você quisesse rodar o bloco do run() antes, não precisaria usar threads.
Como diriam estes mesmos autores: Quando o assunto é threads, pouca coisa é garantida.
Se por acaso o metodo run() ser executado primeiro.
No metodo main() dentro do bloco sincronizado ele vai chamar o metodo wait(), o que pode acontecer neste cenário ? (Não sei se eu fui muito claro na minha dúvida)
A main thread iria ficar travada no wait até que um spurious wakeup ocorresse, isso se ocorresse…
Se o usuário tentar fechar a aplicação (e rodar em alguma outra thread, como a do Swing, algum codigo com System.exit(0)), o wait também lançaria uma InterruptedException, o que liberaria o programa.
Tanto o wait quanto o sleep sofrem desse problema chamado spurious wakeup. Basicamente, existe a possibilidade deles acordarem antes do previsto. No caso do sleep, isso geralmente não é um problema, pois ele é comumente usado para implementar uma pausa, não para aguardar uma condição.
Agora, para o wait, isso pode ser problemático. Então, o que se recomenda, é que todo código de um wait esteja dentro de um while. Isso não só evita o spurious wakeup como também torna mais explicíta que condição o wait está esperando. Exemplo:
Um programa também finaliza se todas as threads que existirem (estejam paradas num wait ou não) forem daemon threads.
Faça o teste:
[code]
public class Teste implements Runnable
{
public void run() {
synchronized (this) {
try {
wait(); //Espera para sempre?
} catch (InterruptedException e) {
throw new RuntimeException(“Thread interrupted!”, e);
}
}
}
}
public static void main (String []args) {
Thread t1 = new Thread(new Teste());
Thread t2 = new Thread(new Teste());
Thread t3 = new Thread(new Teste());
t1.setDaemon(true);
t2.setDaemon(true);
t3.setDaemon(true);
t1.start();
t2.start();
t3.start();
}[/code]
Retirando os setDaemon, essa aplicação nunca finalizará. Mas como nesse caso as threads são Daemons, elas terminam normalmente. Isso porque, após a Thread do main acabar, só restarão Daemon threads. E threads desse tipo não são capazes de manter o sistema “vivo”.
Olá pessoal novamente …
Estou com outra dúvida pessoal ! Tipo na linha 6 quando eu faço sinchronized(b) eu to proibindo outro objeto de entrar no bloco sincronizado é isso né ? Mas na verdade eu to “fechando” qual objeto quando eu faço sinchronized(this) na linha 20… :roll: :hunf:
Na linha 6, você proíbe outras threads (não outro objeto) de ter acesso ao código sincronizado por um objeto de lock (nesse caso b) enquanto outra thread estiver ativa dentro dele.
Ou seja, quando a thread que entrou no bloco da linha 6 dorme no wait da linha 9, ela libera para que outra thread entre no sinchronized da linha 20 e a desperte com o notify da linha 24.
Só lembrando a dica que te dei no outro post:
Threads são não objetos. A classe Thread é só o executor da thread, mas a thread em si é uma linha de execução.
Também, com os códigos mal estrurados (como o do exemplo que vc me passou e diversos que já vi do Camilo) que ela põe no livro, não há quem aprenda mesmo.
Mas fique tranquilo. Threads é realmente um assunto espinhoso, principalmente para quem está vendo da primeira vez.
Vai postando as dúvidas por aqui que a gente vai esclarecendo, quando possível.