Search code examples
javaarraysmultithreadingthread-sleepnotify

Java threads starting other threads, each writing into array


Completely new to Java, however I have to, somehow, make this work. I hope You guys can get me on the right path.

The program has to create N threads and an array of N elements. The first thread should write a random number into the array (here - resultArray), call (or create) the next thread (which will do the same) and sleep until the last thread notifies all other sleeping threads.

So, am I doing this correctly so far? How can I make the run() access demo's resultArray and write in the thread's random number? Also, how can run() reach other threads (of the threadList) to notify them?

Thank You.

public class gijos extends Thread {

    private int length; 
    private int position;

    public gijos(int arrPos) { 
      position = arrPos;
    } 

    public int getPosition(){
       return position;
    }

    public void run() {   
             Random rand = new Random();
             int  n = rand.nextInt(51) + 1;
    }

public class demo { 

    public static void main (String[] args) { 

            System.out.println("Array length / thread count:");

            Scanner s = new Scanner(System.in);
            int N = s.nextInt();

            int[] resultArray = new int[N];

            gijos[] threadList = new gijos[N]; 

            for(int i = 0; i < N; i++){
                threadList[i] = new gijos(i);
            } 

    }

}

Solution

  • Here you have an example worker class:

    public class ArrayWorker implements Runnable {
        private static final List<ArrayWorker> threadList = new LinkedList<>();
        private static final Random rnd = new Random(System.currentTimeMillis());
    
        private final int[] array;
        private final int index;
    
    
        public ArrayWorker(final int[] array, final int index) {
            if (index > array.length - 1) {
                throw new IndexOutOfBoundsException(String.format("%d", index - array.length));
            }
    
            this.array = array;
            this.index = index;
            System.out.println(this + " has been created");
        }
    
    
        @Override
        public void run() {
            System.out.println(this + " run()");
            this.array[this.index] = rnd.nextInt(100);
    
            if (index < array.length - 2) {
                final ArrayWorker worker = new ArrayWorker(array, index + 1);
    
                System.out.println(this + " has created: " + worker);
                new Thread(worker).start();
    
                threadList.add(this);
                try {
                    synchronized (this) {
                        System.out.println(this + " is now waiting");
                        this.wait();
                        System.out.println(this + " got notified");
                    }
                } catch (InterruptedException ex) {
                    System.out.println("Error while waiting for termination");
                    threadList.remove(this);
                }
            } else {
                threadList.forEach(worker -> {
                    synchronized(worker) {
                        System.out.println(this + " notifying: " + worker);
                        worker.notify();
                    }
                });
            }
        }
    
        @Override
        public String toString() {
            return "WorkerThread[" + index + "]";
        }  
    }
    

    Here the usage:

    public static void main(String[] args) {
        final int[] myArray = new int[10];
    
        System.out.println("MainThread creating first WorkerThread and awaiting termination of last WorkerThread");
        Thread t = new Thread(new ArrayWorker(myArray, 0));
        try {
            t.start();
            t.join();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            System.exit(-1);
        }
    
        System.out.println("Last WorkerThread finished");
        for (int i : myArray) {
            System.out.print(i + " ");
        }
        System.out.println();
    }
    

    Example output:

    MainThread creating first WorkerThread and awaiting termination of last WorkerThread
    WorkerThread[0] has been created
    WorkerThread[0] run()
    WorkerThread[1] has been created
    WorkerThread[0] has created: WorkerThread[1]
    WorkerThread[1] run()
    WorkerThread[0] is now waiting
    WorkerThread[2] has been created
    WorkerThread[1] has created: WorkerThread[2]
    WorkerThread[1] is now waiting
    WorkerThread[2] run()
    WorkerThread[3] has been created
    WorkerThread[2] has created: WorkerThread[3]
    WorkerThread[2] is now waiting
    WorkerThread[3] run()
    WorkerThread[3] notifying: WorkerThread[2]
    WorkerThread[3] notifying: WorkerThread[1]
    WorkerThread[2] got notified
    WorkerThread[3] notifying: WorkerThread[0]
    WorkerThread[1] got notified
    WorkerThread[0] got notified
    Last WorkerThread finished
    Results:
    10 25 73 7