Ich würde das mit einem Interface über einen Listener machen. Hab dir mal ein kleines Beispiel zusammengebaut:
Zuerst mal das Interface definieren mit den Methoden, die man benötigt:
[code=Java]
package de.test;
public interface IDemoListener {
public void doNext(Integer count);
public void doFinish();
}
[/code]
Den Thread hab ich mal als eigene Klasse erstellt, hier wird die Arbeit erledigt und bericht erstattet. Als Beispiel hab ich 2 Worker Threads gebaut, einen einfachen mit nur einem Listener und einen "allgemeinen", der beliebig viele Listener bedienen kann.
Der einfache:
[code=Java]
package de.test;
public class WorkerSimple extends Thread {
private IDemoListener listener;
private int maxCount;
public WorkerSimple(int maxCount) {
this.maxCount = maxCount;
}
public void setListener(IDemoListener listener) {
this.listener = listener;
}
@Override
public void run() {
for (int i=0; i<maxCount; i++) {
try {
Thread.sleep(500); // 0.5s warten
}
catch (InterruptedException ie) {
}
listener.doNext(i);
}
listener.doFinish();
}
}
[/code]
Der allgemeine:
[code=Java]
package de.test;
import java.util.ArrayList;
public class Worker extends Thread {
private ArrayList<IDemoListener> listener;
private int maxCount;
public Worker(int maxCount) {
this.listener = new ArrayList<IDemoListener>(0);
this.maxCount = maxCount;
}
public void addListener(IDemoListener listener) {
if (listener != null) {
this.listener.add(listener);
}
}
@Override
public void run() {
for (int i=0; i<maxCount; i++) {
try {
Thread.sleep(1000); // 1s warten
}
catch (InterruptedException ie) {
}
fireNext(i);
}
fireFinish();
}
private void fireNext(Integer count) {
for (IDemoListener dl : listener) {
dl.doNext(count);
}
}
private void fireFinish() {
for (IDemoListener dl : listener) {
dl.doFinish();
}
}
}
[/code]
Jetzt noch die Demo-Klasse, welche die Worker startet. Das könnte in deinem Fall z.B. die GUI sein und wenn du auf einen Start-Button klickst, könnte die Progressbar angezeigt werden und über das Event aktualisiert werden.
Ich habe die Listener hier auf 2 verschiedene Weisen implementiert, nur zu Demo-Zwecken, einmal implementiert die Klasse selbst einen Listener und für den WorkerSimple hab ich eine innere Klasse benutzt. Du kannst dir quasi aussuchen, wie es dir lieber wäre:
[code=Java]
package de.test;
public class Demo implements IDemoListener {
private int progress = 0;
public Demo() {
}
public void startWorker(int maxCount) {
Worker worker = new Worker(maxCount );
worker.addListener(this); // IDemoListener übergeben
worker.start();
WorkerSimple simple = new WorkerSimple(maxCount);
simple.setListener(new IDemoListener() {
@Override
public void doNext(Integer count) {
System.out.println("Simple-Forschritt: " + count);
}
@Override
public void doFinish() {
System.out.println("Simple ist fertig");
}
});
simple.start();
}
@Override
public void doNext(Integer count) {
progress = count;
System.out.println("Worker-Forschritt: " + progress);
}
@Override
public void doFinish() {
System.out.println("Programmende");
System.exit(0);
}
}
[/code]
Und letztlich die Start-Klasse für das Programm:
[code=Java]
package de.test;
public class Start {
public static void main(String[] args) {
Demo demo = new Demo();
demo.startWorker(10);
}
}
[/code]
Um zu zeigen, daß die beiden Thread unabhängig voneinander arbeiten, wartet der WorkerSimple nur 0.5s bis zum nächsten Schritt, der Worker wartet 1s.
Ich hoffe, das Beispiel ist nicht zu schwer zu verstehen ;-)