Home > OS >  Switching between threads and letting loop finish Java
Switching between threads and letting loop finish Java

Time:11-01

I am trying to use two threads to alternate between each other to count to a certain random number. For example, if thread A is assigned with a random number 4 and thread B is assigned with a random number 7, I am looking for output like this:

Thread A:1
Thread B:1

Thread A:2
Thread B:2

Thread A:3
Thread B:3

Thread A:4
Thread B:4

Thread A:5

Thread A:6

Thread A:7

So basically it will switch between threads and if one thread is done counting to the random number it will stop and let the other thread finish counting to the random number. This is the code I have so far:

public class Test extends Thread {
public static Object sync = new Object();
    public void run() {

        Random rand = new Random();
        // generate random number 1-20;
        int random = rand.nextInt((20 - 1)   1)   1;
        for (int i = 0; i < random; i  ) {

            synchronized (sync) {
                try {
                    sync.notify();
                    System.out.println(i);
                    sync.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

I have been at a dead end for a while and I have no idea on what to do. This is my first time using threads so I could use some help. If anyone knows how to do this let me know as I have tried so much but nothing has worked. Thanks in advance.

CodePudding user response:

This is a little, basic. I'm not a fan of static in this context, but for a demonstration, it should help prove the point

Essentially, you need a "counter" which can keep track of the number of "active" threads, if there is only one, you don't need to "wait", for example...

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.DataFormatException;

public class Main {

    public static void main(String[] args) throws IOException, DataFormatException {
        new Thread(new Test(), "One").start();
        new Thread(new Test(), "Two").start();
    }

    public static class Test implements Runnable {

        public static Object sync = new Object();
        public static AtomicInteger counter = new AtomicInteger(0);

        public void run() {

            counter.incrementAndGet();

            Random rand = new Random();
            // generate random number 1-20;
            int random = rand.nextInt((20 - 1)   1)   1;
            String name = Thread.currentThread().getName();
            System.out.println(name   " count to "   random);
            for (int i = 0; i < random; i  ) {

                synchronized (sync) {
                    try {
                        sync.notify();
                        System.out.println(name   " "   i);
                        int count = counter.get();
                        if (count > 1) {
                            sync.wait();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }

            counter.decrementAndGet();
            synchronized (sync) {
                sync.notify();
            }
        }
    }
}

And, because I don't like to abuse static (sync in this context could be argued, but as demonstration of the basic concept)

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.DataFormatException;

public class Main {

    public static void main(String[] args) throws IOException, DataFormatException {
        Object lock = new Object();
        AtomicInteger counter = new AtomicInteger(0);

        new Thread(new Test(lock, counter), "One").start();
        new Thread(new Test(lock, counter), "Two").start();
    }

    public static class Test implements Runnable {

        private Object lock;
        private AtomicInteger counter;

        public Test(Object lock, AtomicInteger counter) {
            this.lock = lock;
            this.counter = counter;
        }

        public void run() {

            counter.incrementAndGet();

            Random rand = new Random();
            // generate random number 1-20;
            int random = rand.nextInt((20 - 1)   1)   1;
            String name = Thread.currentThread().getName();
            System.out.println(name   " count to "   random);
            for (int i = 0; i < random; i  ) {

                synchronized (lock) {
                    try {
                        lock.notify();
                        System.out.println(name   " "   i);
                        int count = counter.get();
                        if (count > 1) {
                            lock.wait();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }

            counter.decrementAndGet();
            synchronized (lock) {
                lock.notify();
            }
        }
    }
}
  • Related