E' un codice MOLTO rozzo ma serve solo a rendere l'idea..e poi devo ancora mangiare e sono affamato pensa quanto possa essere bassa la qualità di questo codice (non controllo tutte le eventuali eccezioni):

codice:
import javax.swing.Timer;
import java.awt.event.*;
import javax.swing.JOptionPane;

class Esempio {

	private Thread [] t;
	private Runnable [] r;
	private Timer timer;
	private int tempo;

	public Esempio () {
		t = new Thread [2];
		r = new Runnable [2];
		timer = new Timer (1000 , new ActionListener () {
			public void actionPerformed (ActionEvent ae) {
				tempo++;
			}
		});
		r [0] = new Runnable () {
			public void run () {
				int durata = Integer.parseInt (JOptionPane.showInputDialog ("Quanti secondi devo restare in esecuzione (metti un numero intero!!)"));
				tempo = 0;
				int j = 0;
				System.out.println ("IO STAMPO ANDANDO A CAPO");
				while (tempo < durata) {
					System.out.println (j+"");
					j++;
					try {
						Thread.sleep (100);
					}catch (InterruptedException ie) {
						System.out.println ("IO THREAD 1 SONO STATO INTERROTTO MENTRE ATTENDEVO");
					}
				}
				System.out.println ("ora mi fermo e faccio partire l'altro thread");
				t [1] = new Thread (r [1]);
				t [1].start ();
			}
		};

		r [1] = new Runnable () {
			public void run () {
				int durata = Integer.parseInt (JOptionPane.showInputDialog ("Quanti secondi devo restare in esecuzione (metti un numero intero!!)"));
				tempo = 0;
				int j = 0;
				System.out.println ("IO NON VADO A CAPO");
				while (tempo < durata) {
					System.out.print (j+"");
					j++;
					try {
						Thread.sleep (100);
					}catch (InterruptedException ie) {
						System.out.println ("IO THREAD 2 SONO STATO INTERROTTO MENTRE ATTENDEVO");
					}
				}
				System.out.println ("ora mi fermo e faccio partire l'altro thread");
				t [0] = new Thread (r [0]);
				t [0].start ();
			}
		};
		t [0] = new Thread (r [0]);		
		timer.start ();
		t [0].start ();
	}

	public static void main (String [] args) {
		new Esempio ();
	}

}
oppure potresti fare un'altra cosa del tipo:
avvii un thread t1
nel run di t1:
while (veraCondizione) {
svolgi ciò che deve svolgere il thread
"crea" e avvia t2
t2.join ()
}