Wie kann man einen Thread in einer anderen Klasse aufrufen?

Nebenläufige Programmierung in Form eines weiteren Threads kann zur Bearbeitung rechenintensiver Prozesse oder zur Ausführung parallel ablaufender Programmstränge - etwa zum Laden grosser Bilder oder für die Ausführung eines Fortschrittsbalkens - verwandt werden. Ein Vorteil liegt darin, dass während der Laufzeit das Programm nicht 'einfriert'.

Das Beispiel demonstriert die gleichzeitige Ausgabe einer Zahlenfolge und deren Fortschrittsanzeige durch einen ProgressMonitor. Zunächst wird eine Klasse erstellt, die in diesem Falle lediglich einen Button zum Aufruf der Threadklasse in einem JFrame bereitstellt. Sie wird in der main()-Methode aufgerufen.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class ThreadInAndererKlasse extends JFrame implements ActionListener {
    
    private final JButton button;
    
    public ThreadInAndererKlasse(){
        
        button = new JButton("auf geht's");
        button.addActionListener(this);
        
        this.add(button);
        this.setSize(300, 300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }
    
    public static void main(String[] args){
        new ThreadInAndererKlasse();
    }

    public void actionPerformed(ActionEvent arg0) {
        MachWas machDoch = new MachWas();
        machDoch.start();
    }
}

Die zweite Klasse stellt eine Instanz eines ProgressMonitor bereit, der den Fortschritt eines rechenintensiven Prozesses anzeigt. Sie muss die Klasse Thread erweitern.
Die Mehode machDochWas() stellt den Kern des Programmes dar. In ihr wird innerhalb einer while-Schleife eine Zählvariable von 0 bis 100 hochgezählt. Bei jedem Durchgang geschieht dreierlei:

import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;

public class MachWas extends Thread {
    
    private ProgressMonitor pm;
    
    int i = 0;
    
    public MachWas(){
        pm = new ProgressMonitor(null, "Fortschritt anzeigen", "", 0, 100);
        pm.setMillisToDecideToPopup(1);
    }
    
    public void run(){
        try {
            machDochWas();
        } catch (Exception e) {
        }        
    }
    
    public void machDochWas(){
        while (!pm.isCanceled() && i<=100) {
            pm.setNote(new Integer(i).toString());
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    pm.setProgress(i);
                }
            });

            System.out.println(i);
            // statt rechenintensiver Aktion
            // Thread kurz unterbrechen
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            i++;
        }
    }

}