Exercicio 9-2 livro Kathy

No livro da Kathy (SCJP 5 Pt) tem um exercicio que pede pra criar uma classe que dispare 3 threads.
Essas threads tem que imprimir 100 vezes uma letra.
A saída final tem que ser:
100 vezes a letra A na mesma linha
100 vezes a letra B na mesma linha
100 vezes a letra C na mesma linha
.
Tentei o seguinte código e as vezes dá certo, as vezes não.
Alguém sabe porque ?

package testKiller7;

public class Ex9_2 extends Thread {
	private StringBuffer s = null;

	public Ex9_2(StringBuffer s) {
		this.s = s;
	}

	@Override
	public void run() {
		synchronized (s) {
			for (int i = 0; i < 100; i++) {
				System.out.print(s);
			}
			System.out.println();
			char temp = s.charAt(0);
			++temp;
			s.setCharAt(0, temp);
		}
	}

	public static void main(String[] args) {
		Ex9_2 t1 = new Ex9_2(new StringBuffer("A"));
		Ex9_2 t2 = new Ex9_2(new StringBuffer("B"));
		Ex9_2 t3 = new Ex9_2(new StringBuffer("C"));
		t1.start();
		t2.start();
		t3.start();
	}
}

Dar um start() em uma thread significa que colocou ela em modo de executável, agora o modo de EXECUTANDO é diferente, quem controla isso é a JVM.

Portanto, dê um join() em todas as suas threads.

[]'s

Deu certo somente nesta sequencia.

t1.start();
t1.join();
t2.startc();
t2.join();
t3.start();
t3.join();

[quote=AUser]Dar um start() em uma thread significa que colocou ela em modo de executável, agora o modo de EXECUTANDO é diferente, quem controla isso é a JVM.

Portanto, dê um join() em todas as suas threads.

[]'s[/quote]

[code]public class BlaBlaBla extends Thread {
private char c;
private BlaBlaBla waitFor;
private void waitFor() {
if (waitFor != null) {
try {
waitFor.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public void run() {
waitFor();
for (int i = 0; i<100; i++)
System.out.print©;
System.out.println();
}

public BlaBlaBla(char c) {
this(c,null);
}
public BlaBlaBla(char c, BlaBlaBla waitFor) {
this.c = c; this.waitFor = waitFor;
}

public static void main(String[] args) {
BlaBlaBla t1 = new BlaBlaBla(‘A’);
BlaBlaBla t2 = new BlaBlaBla(‘B’,t1);
BlaBlaBla t3 = new BlaBlaBla(‘C’,t2);
t2.start();
t1.start(); //pode trocar a hordem a vontade
t3.start();
}
}[/code]

outra forma, caso não queira passar pelo construtor é adcionar o método

public void setWaitFor(BlaBlaBla waitFor) { this.waitFor = waitFor; }

e depois mudar o main assim

[code] public static void main(String[] args) {
BlaBlaBla t1 = new BlaBlaBla(‘A’);
BlaBlaBla t2 = new BlaBlaBla(‘B’);
BlaBlaBla t3 = new BlaBlaBla(‘C’);

  t3.setWaitFor(t2);
  t2.setWaitFor(t1);

  t2.start();
  t1.start(); //pode trocar a hordem a vontade
  t3.start();

}[/code]

Enfim existe muitas formas de solucionar o problema, mas o fato é que você precisa usar join para garantir a ordem que as coisas serão feitas

[quote=antonioedirane]Deu certo somente nesta sequencia.

t1.start(); t1.join(); t2.startc(); t2.join(); t3.start(); t3.join(); [/quote]

Isso que vc colocou funciona, masss não é abordagem correta…

o fato é q vc esta startando t1, e ta dando um JOIN através da thread main, e a thread main fica esperando ate t1 acabar, e so ai strata a thread2 …

e assim por diante…

as threads acabam sem ser startada simultaneamente, o join, deveria ser feito de dentro da t2, esperando por t1, e t3 deveria dar um join para esperar por t2 …

da forma como vc esta fazendo, as threads não startam simultaneamente…