2

I am having troubles with stopping a thread which is started from outside the class using a actionPerformed on a JButton. Code of the thread class below.

public synchronized void run ()
{
    try
    {
        do
        {
            int minuta = vrijeme / 60;
            int sekundi = vrijeme % 60;

            System.out.println(minuta+" "+sekundi);

            vrijeme = vrijeme - 1;
            delay = delay - 1000;

            if (minuta == stani && sekundi == 0)
            {

            }



            try 
            {
                Thread.sleep(1000);
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
        }
        while (delay != 0);
        {
                //
        }
    }
    catch (Exception e)
    {
        System.out.println("Stao" + e);
    }
}
void pokreniThread()
{
    (new Thread(new OdredenoVrijeme())).start();
}
synchronized public void zaustaviThread()
{
    try
    {
        (new Thread(new OdredenoVrijeme())).wait();
    }
    catch (Exception e)
    {
        System.out.println("stao" +e);
    }
}

}

Every time i call .sleep() .wait() or anything similar i get the following catch message:

java.lang.IllegalMonitorStateException
flavio.donze
  • 7,432
  • 9
  • 58
  • 91

3 Answers3

3

Under Java, you cannot have a sleep in the main process. Create a sub-thread, which will do the sleep, then post a message to a handler in the main-thread, to do something after the timeout.

If you want to stop a thread itself, set a variable inside the thread like is_stopping=true, then inside the thread you could set a variable is_running=false after the thread stops itself.

is_running=true;
while (is_running & !is_stopping)
{
   do_something();
   sleep();
}
is_stopping=false;
is_running=false;
Bart Mensfort
  • 995
  • 11
  • 21
  • Yep, works. Figured that i cannot call the sleep() command form outside the run() so i used a volatile boolean and a if statement to sleep() if the boolean was equal to true. Thank you a lot! – Meho HoMe Hatić Apr 17 '16 at 19:01
0

In java the main thread is playing a scheduler part in the program. So in a multithreading situation you have these parts:

  • scheduler/controller
  • provider
  • customer

The main thread should always play the scheduler/controller part of the program. BTW you are not using multithreading in a good way. use synchronized when its absolutely necessary. look at the following code. you should use synchronization like this:

public class BlockingQueue<T> {

private Queue<T> queue = new LinkedList<T>();
private int capacity;

public BlockingQueue(int capacity) {
    this.capacity = capacity;
}

public synchronized void put(T element) throws InterruptedException {
    while(queue.size() == capacity) {
        wait();
    }

    queue.add(element);
    notify(); // notifyAll() for multiple producer/consumer threads
}

public synchronized T take() throws InterruptedException {
    while(queue.isEmpty()) {
        wait();
    }

    T item = queue.remove();
    notify(); // notifyAll() for multiple producer/consumer threads
    return item;
}
mrphoenix13
  • 679
  • 6
  • 10
0

You cannot stop a thread from an external context. The thread should stop itself when some condition changes. You have to hold a flag in your thread that you want to stop, and the thread to check the flag in a loop. If the flag is changed, then the thread itself should do nothing and it will exit by itself

AdrianS
  • 1,980
  • 7
  • 33
  • 51