1

I have Runnable class:

package com.example.testtest;

public class FootballRunner implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("Running " + Thread.currentThread().getId() + " " + Math.random());
            try {
                Thread.sleep(1_000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

and have the main class:

package com.example.testtest;

public class TestScheduling {
    public static void main(String[] args) throws InterruptedException {
        FootballRunner footballRunner = new FootballRunner();
        Thread t1 = new Thread(footballRunner, "one");
        t1.start();
        t1.wait();
    }
}

but when I try to make it wait it throws an exception:

Exception in thread "main" java.lang.IllegalMonitorStateException: current thread is not owner
    at java.base/java.lang.Object.wait(Native Method)
    at java.base/java.lang.Object.wait(Object.java:338)
    at com.example.testtest.TestScheduling.main(TestScheduling.java:8)

What does "current thread is not owner" mean? How I can make t1 to pause?

ilhan
  • 8,700
  • 35
  • 117
  • 201
  • @aled when I wrap t1.wait with a synchronized keyword it never waits. – ilhan Jun 14 '23 at 11:39
  • It seems like you do not understand the concept of wait/notify methods, more details here - https://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java . Also would be great to know the whole scenario of your program to be able to advice you a proper solution. – Maksym Kosenko Jun 14 '23 at 11:46

3 Answers3

1

The methods wait and notify need to be used inside of synchronized methods or blocks, where they're called on the object whose intrinsic lock is being held. Entering the synchronized block gives a thread the chance to check the state of the object without interference from other threads, so that it can decide whether it needs to wait.

The wait/notify mechanism has a lot of assumptions baked into it and is pretty involved, for details see the Java concurrency tutorial. In particular there is lots of good information in https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html. but it sounds like it's too complicated for what you want.

If you want to pause for a fixed amount of time, have the pausing thread use Thread.sleep. sleep is a static method that always affects the current thread, you can't use it to put another thread to sleep. If you could, that would be a security issue; malicious code could suppress other threads.

If you want the thread to pause until some other thread tells it it can go, CountdownLatch is a simpler alternative.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
-1

If you want to change your task state, the better way is to design a FSM (Finite State Machine), that means :

  1. set task default state, false for example
  2. change it to true when you call t1.start()
  3. change it to false when you wanna stop it

something like below

private AtomicBoolean running = new AtomicBoolean(false);

@Override
public void run() {
    final boolean success = running.compareAndSet(false, true);
    if (! success) {
        throw new IllegalStateException("xxxxx");
    }
    while (running.get()) {
        System.out.println("Running " + Thread.currentThread().getId() + " " + Math.random());
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

public void stop()  {
    if (! running.compareAndSet(true, false)) {
        throw new IllegalStateException("stop task failure.");
    }
}


public static void main(String[] args) throws InterruptedException {
    FootballRunner footballRunner = new FootballRunner();
    Thread t1 = new Thread(footballRunner, "one");
    t1.start();
    // sleep for a while to wait t1 start
    Thread.sleep(100);
    footballRunner.stop();
}
lu kevin
  • 9
  • 3
  • Which thread calls `wait()` is irrelevant. The salient fact is that there is no `synchronized` block around the `wait()`. – user207421 Jun 14 '23 at 11:55
-2
  1. Object.wait() use in conjunction with synchronzed.
  2. by Thread.sleep(long millis)
hyz
  • 1
  • 2
  • When synchronized keyword is used it never runs t1.wait(). And t1.sleep(10_000L) has no effect. – ilhan Jun 14 '23 at 11:40