开发者

java.lang.IllegalThreadStateException

开发者 https://www.devze.com 2023-04-02 11:25 出处:网络
I am working with threads. However when I try to start a thread, I get a Exception. In concrete java.lang.IllegalThreadStateException. My code is:

I am working with threads. However when I try to start a thread, I get a Exception. In concrete java.lang.IllegalThreadStateException. My code is:

public void readCommand() {
    readThread = new Thread("Thread for reading") {
        public void run() {
            while (running)开发者_如何学Go {
                readBuffer = usbservice.receiveData();
                put(readBuffer);
            }
        }
    };
    readThread.start();
}

What could the problem be?


You are storing the thread in a field. If the method is called in two threads, the readThread.start() can be called twice for the same thread. You need to ensure readCommand is not called multiple times and perhaps not start the readThread again if its already running. e.g. you can synchronized the method and check readThread before you start.


A thread will throw the exception when calling start if the thread's state (as retrieved by Thread.currentThread().getState() is anything other than NEW.

The source;

public synchronized void start() {
    /*
     * A zero status value corresponds to state "NEW".
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
    group.add(this);
    start0();
    if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
}

This means, your thread is in one of the other states, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING or TERMINATED.

You could have a look at the state of the threads via a thread dump or JConsole to see what yours is doing. You can programmatically take a thread dump right before the call to start using something like tempus-fugit if that helps.

UPDATE: In response to your comments, if you interrupt a thread which in your case, I assume will set the running flag to false, the thread will still be RUNNABLE. To 'resume' work on the thread (again, I'm assuming that's what you want to do), you would change the running flag again. Calling start will fail because it's already started. You could also let the thread die on interruption and then just create a new instance of a Thread and "start" that one as an alternative.


Have a look at oracle documentation page about Thread.start()

public void start()

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).

It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

Throws: IllegalThreadStateException - if the thread was already started.

In multi-threaded environment, you have to make sure that above Thread is started exactly once. If you are trying start() on a Thread, which has been already started, you are bound to get above exception.


If the thread has already been started, you need to use run() instead of start().


In fact, the call process is:

  • From main method: controller.main(usbservice);

  • In controller object:

    @Override
    public void main(Object argv) {
        if(this.writer == null)
            this.writer = new CommandWriting(usbservice);
        if(this.reader == null)
            this.reader = new CommandReading(usbservice);
        reader.readCommand();
    }
    
  • In object reader is the readCommand method.

Then, it is only called once.


just Initialize Your Thread with

 Thread abc =new Thread(){
}

& call start() when you need multiple times after thread finish task.

Hope this works for you

0

精彩评论

暂无评论...
验证码 换一张
取 消