简体   繁体   中英

Java Thread - synchronization thread

I have something like this:

 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;
}
 }

So, if I run program withou arguments (I mean String args[]) program works okay, but if I set agument = abort

My program should print something like this:

Task CREATED R. ... aborted. Task ABORTED 31700

sometimes he print good but sometimes he print something like this:

Task CREATED RRTask ABORTED 58891

and something like this:

Task CREATED RR ... ready. Task READY 70000

but I don't know why, so my question is:

How to correctly synchronise threads so they can do what they should?

There isn't any meaningful shared state (there are some flags that get set, where the code that reads them is not synchronizing so they may not be getting the updated value, but those fields don't seem to be used) so synchronization is not an issue here.

Your task's run method doesn't handle interruption (for instance, it doesn't check Thread.currentThread().isInterrupted() ) so calling interrupt has no effect. Interruption requires the task being interrupted to cooperate by checking whether it's been interrupted and taking measures to end itself. You could change the loop to test for interruption, with something like:

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

You have one thread concatenating chars onto a string, and how much CPU time it gets depends on the OS, it has to decide how much time to give each thread here and also how much time to give the JVM versus other processes executing on your computer. Sometimes your task may finish before the thread trying to interrupt it, other times it may not, which affects what state gets printed out. You should expect to get different results when you run it repeatedly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM