---------- t1.java ------------
import java.awt.*;
import java.io.*;

public class t1 extends Thread {
  private String str;

  public t1( String _s ) {
    str = new String( _s );
  }

  public void run() {
    for( int i = 0 ; i < 10 ; i++ )
      System.out.println(str);
  }
}

------- Principal.java -----------
import java.io.*;

public class principal {
  public static void main( String argv[] ) {
    String s = new String( "Oi mundo" );
    t1 t = new t1( s );
    s = new String( "Oi de novo" );
    t1 tt = new t1( s );

    System.out.println("Vou iniciar thread...");
    t.start();
    System.out.println("... mas nao espero o fim.");
    System.out.println("Vou iniciar outra thread...");
    tt.start();
    try {
      tt.join();
    } catch( Exception e ) {}
    System.out.println("... mas desta vez esperei.");
  }
}

---------- semaforo.java ------------
import java.awt.*;

public class semaforo {
  volatile private int value = 0;

  public synchronized void Wait() {
    while( true ) {
      if( value > 0 )
        value--;
      else {
        try {
          wait();
        } catch( Exception e ) {}
      }
    }
  }
  public synchronized void Signal() {
    value++;
    notify();
  }
}
