Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syncronisize two looping Java-Thread

Two threads are running parallel:

Thread1:

while(...) {
  <-- wait until thread2 is not in update()
  doWork();
}

Thread2:

while(...) {
  doWork();
  <-- wait until thread1 is not in work()
  update();
}

I think the examples above explain what I try to do, but I have not really an idea how to do this synchronization. The update()-method of thread2 is critical an while it is executed thread2 have to wait.

Edit:

Thanks so far for the answers. More than one is working well. I was asked what I am trying to do and I want to give an short update for that.

Based on the currentState thread2 calculates the nextState and swap both before it repeats calculating endless. thread1 displays the 'currentState' in the gui for the user.

Thread1 should not display the currentState while the swaping is currently in progress.

Thats all.

like image 692
testo Avatar asked Feb 11 '26 06:02

testo


1 Answers

Using a Lock would be the easiest approach. Here's a demo of how simple it is. We create two Runnable and start them running under two threads. We then wait for 30 seconds and then interrupt them and wait for them to finish.

// Lock shared between both threads.
final Lock lock = new ReentrantLock();
// Random numbers.
final Random random = new Random();

public void test() throws InterruptedException {
    // Process 1 is a runnable.
    Runnable p1 = new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    // Grab the lock.
                    lock.lock();
                    // Do my work.
                    doWork();
                } catch (InterruptedException ex) {
                    System.out.println("P1 Interrupted!");
                    break;
                } finally {
                    // Release the lock in a `finally` to ensure it can never be left locked.
                    lock.unlock();
                }
            }
        }

        private void doWork() throws InterruptedException {
            long wait = random.nextInt(2000);
            System.out.println("P1 Working ... " + wait);
            // Wait up to 2 seconds.
            Thread.sleep(wait);
            System.out.println("P1 Work done");
        }

    };

    Runnable p2 = new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    // Do my work.
                    doWork();
                    // Grab the lock.
                    lock.lock();
                    // Do my update.
                    update();
                } catch (InterruptedException ex) {
                    System.out.println("P2 Interrupted!");
                    break;
                } finally {
                    lock.unlock();
                }
            }
        }

        private void doWork() throws InterruptedException {
            long wait = random.nextInt(2000);
            System.out.println("P2 Working ... " + wait);
            // Wait up to 2 seconds.
            Thread.sleep(wait);
            System.out.println("P2 Work done");
        }

        private void update() throws InterruptedException {
            long wait = random.nextInt(2000);
            System.out.println("P2 Update ... " + wait);
            // Wait up to 2 seconds.
            Thread.sleep(wait);
            System.out.println("P2 Update done");
        }

    };

    // Create the two threads.
    Thread t1 = new Thread(p1);
    Thread t2 = new Thread(p2);
    // Start them up.
    t1.start();
    t2.start();
    // Wait 30 seconds - with narrative.
    for (int i = 0; i < 30; i++) {
        Thread.sleep(1000);
        System.out.println("Tick");

    }
    // Stop them.
    t1.interrupt();
    t2.interrupt();
    // Wait for them to stop.
    t1.join();
    t2.join();

}

Running this should demonstrate one of the problems with your design. Notice that the P2 Update rarely gets called. This is because P1 spends very little time with the lock released and so starves the other thread. See how in p1 it will lock.unlock() and then almost immediately do a lock.lock() again as it starts the loop again.

like image 106
OldCurmudgeon Avatar answered Feb 13 '26 16:02

OldCurmudgeon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!