Home > Software engineering >  Write out a letter every interval every ms multithreading java
Write out a letter every interval every ms multithreading java

Time:10-20

I'm currently working on a problem where I have to:

Write out a letter, x amount of times, after x amount of ms. Use 4 multithreads, 3 of them start right away 1 of them starts when one of the 3 is finished.

For example: A, 10, 100, has to write out A ever 10 times every 100 miliseconds.

Im currently stuck on syncing the multithreads for them to work together at adding one sum rather than them working seporatley. Could you advise how to sync it together for it to write out the above?

Here is my code:

public class PrinterThread extends Thread {

    private String letter;
    private int internal;
    private int amount;

    
    public PrinterThread() {
        for (int i = 1; i <= internal; i  ) {
            System.out.println(letter);
        }
        synchronized (this){
            internal  ;
        }

        try {
            Thread.sleep(amount);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Main {
    public static void main(String[] args) {



        PrinterThread printerThread = new PrinterThread();
        PrinterThread printerThread1 = new PrinterThread();
        PrinterThread printerThread2 = new PrinterThread();
        PrinterThread printerThread3 = new PrinterThread();

        printerThread.run();
        printerThread1.run();
        printerThread2.run();
        printerThread3.run();

    }
}

CodePudding user response:

Use a BlockingQueue for synchronisation, but you do need to join with the threads from your main method otherwise your main will exit the JVM before the threads finish (or possibly even before they start).

public class PrinterThread implements Runnable {
    private String letter;
    private int copies;
    private int amount;
    
    public PrinterThread(String letter, int copies, int amount) {
        this.letter = letter;
        this.copies = copies;
        this.amount = amount;
    }

    public void run() {
        for (int i = 0; i < copies; i  ) { 
            System.out.println(letter.repeat(copies));

            try {
                Thread.sleep(amount);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        QUEUE.offer(0);
    }
}

public class Main {

    private static BlockingQueue<Integer> QUEUE = new ArrayBlockingQueue<>(4); // at least as large as the number of threads

    public static void main(String[] args) {
        Thread printerThread1 = new Thread(new PrinterThread("A", 10, 100));
        Thread printerThread2 = new Thread(new PrinterThread("B", 20, 50));
        // etc

        printerThread1.start();
        printerThread2.start();
        // etc

        QUEUE.take(); // blocking call
        new Thread(new PrinterThread("D", 30, 80)).start();

        // wait for threads to finish
        printerThread1.join();
        printerThread2.join();
        // etc
    }
}

Disclaimer: This answer was thumbed in via my phone, so it may not work correctly or even compile, but there’s a good chance it will work.

CodePudding user response:

Write out a letter, x amount of times, after x amount of ms. Use 4 multithreads, 3 of them start right away 1 of them starts when one of the 3 is finished.

You obviously need to create a PrinterThread constructor which takes the letter, the amount of times, and amount of millis.

I'm currently stuck on syncing the multithreads for them to work together at adding one sum rather than them working separately.

I'm not sure about the sum. If you are asking how you can start the 3rd thread then there are a number of different ways to do this. I would lock on a lock object and pass in a boolean in the constructor about whether or not the thread should wait() on the lock. As each of the other threads finish they would call notify() on the lock.

 private static final Object lock = new Object();
 ...

 public class PrinterThread {
    public PrinterThread(char letter, int times, int millis, boolean waitForOthers) {
        this.letter = letter;
        this.times = times;
        this.millis = millis;
        if (waitForOthers) {
           synchronized (lock) {
              // wait for one of the others to notify us
              lock.wait();
           }
        }
    }
    public void run() {
       ...
       synchronized (lock) {
          // notify the lock in case another thread is waiting
          lock.notify();
       }
 }

Then start 3 PrinterThreads with a value of false and 1 of them with a value of true so that it waits.

  • Related