1

私はこのようなものを持っています:

 enter code here

public class Main {

public static void main(String[] args) throws InterruptedException {
    StringTask task = new StringTask("A", 100000);
    System.out.println("Task " + task.getState());
    task.start();
    if (args.length > 0 && args[0].equals("abort")) {

        Thread t = new Thread(() -> {
            Thread.currentThread();
            try {
                Thread.sleep(1000);
                task.abort();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        });
        t.start();
    }
    while (!task.isDone()) {
        Thread.sleep(500);
        switch (task.getState()) {
        case "RUNNING":
            System.out.print("R.");
            break;
        case "ABORTED":
            System.out.println(" ... aborted.");
            break;
        case "READY":
            System.out.println(" ... ready.");
            break;
        default:
            System.out.println("uknown state");
        }

    }
    System.out.println("Task " + task.getState());
    System.out.println(task.getResult().length());
}

}

class StringTask implements Runnable {
private String word;

private int nr;
private boolean stopThread = false;
private String result = "";
private String state = "";
private boolean done = false;
private boolean end = false;
public Thread thread;

public StringTask(String s, int n) {
    this.word = s;
    this.nr = n;
    this.state = "CREATED";
}

public void STOP() {
    this.stopThread = true;
}

public void run() {
    this.state = "RUNNING";
        try {
            for (int i = 0; i < nr; i++) {
                result += word;
            }
            this.state = "READY";
            this.done = true;
        } catch (Exception e) {
            this.state = "ABORTED";
            this.done = false;

        }

    }

public synchronized void start() {
    thread = new Thread(this);
    thread.start();
}

public synchronized void abort() throws Exception {
    thread.interrupt();
    this.end = true;
    this.done = true;
    this.state = "ABORTED";

}

public String getResult() {
    return this.result;
}

public String getState() {

    return this.state;
}

public boolean isDone() {
    return this.done;
}
 }

したがって、引数なしでプログラムを実行すると (String args[] を意味します)、プログラムは問題なく動作しますが、agument = abort を設定すると

私のプログラムは次のように出力するはずです:

タスク CREATED R. ... は中止されました。タスクが中止されました 31700

うまく印刷することもあれば、次のようなものを印刷することもあります。

タスクが作成されました RRTask が中止されました 58891

そしてこのようなもの:

タスク作成済み RR ... 準備完了。タスク準備完了 70000

しかし、理由がわからないので、私の質問は次のとおりです。

スレッドを正しく同期して、スレッドがすべきことを実行できるようにする方法は?

4

1 に答える 1

1

意味のある共有状態はありません (設定されるフラグがいくつかあります。フラグを読み取るコードは同期していないため、更新された値を取得していない可能性がありますが、それらのフィールドは使用されていないようです)。したがって、同期はここでは問題ではありません。

タスクの run メソッドは割り込みを処理しない (たとえば、 をチェックしないThread.currentThread().isInterrupted()) ため、割り込みを呼び出しても効果はありません。中断は、中断されたタスクが中断されたかどうかを確認し、それ自体を終了するための措置を講じることで連携する必要があります。次のような方法で、ループを変更して中断をテストできます。

       for (int i = 0; i < nr; i++) {
            result += word;
            if (Thread.currentThread().isInterrupted()) {
                break;
            }
        }

文字列を文字列に連結する 1 つのスレッドがあり、それが取得する CPU 時間は OS によって異なります。ここで各スレッドに与える時間と、コンピューターで実行されている他のプロセスに対して JVM に与える時間も決定する必要があります。 . スレッドが中断しようとする前にタスクが終了する場合もあれば、終了しない場合もあり、出力される状態に影響します。繰り返し実行すると、異なる結果が得られることを期待する必要があります。

于 2016-05-04T19:21:10.400 に答える