Skip to content
Advertisement

Two threads prints one character of a string twice, one by one?

I have troubles with the following task:

Both threads access the object of the class Print and print in reverse order the value of the variable type String, letter by letter, where each letter is printed with a hyphen (–). Example : Input = NAME. Output = E-E-M-M-A-A-N-N.

What I’ve done is the following:

public class Print implements Runnable {
    private String string;
    Print(String string) {
        this.string = string;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = string.length()-1; i >= 0; i--) {
   
            System.out.print(string.charAt(i) + "-");
                
        }
            
    }
    
}

public class Task1 {
    public static void main(String[] args) {
        Print r = new Print("NAME");
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start(); 
    }
}

And it prints usually E-M-A-N-E-M-A-N, but it can be different. How do I make sure that it always prints the desired result? Thank you very much

Advertisement

Answer

As I mentioned in the comment, you need CyclicBarrier, which will coordinate the two threads and not let one or the other run ahead.

However, if you don’t want the last - character printed, there needs to be another coordination between the two threads for i == 0. One thread would print the last letter plus one -, then notify the other thread to go ahead and print just the last letter. This can be done with an atomic variable and a CountDownLatch. Who wins the update on the atomic variable will print letter-dash and count down the latch, the loser will wait on the latch and print the letter.

class Print implements Runnable {
    private String string;

    private CyclicBarrier cb = new CyclicBarrier(2);
    private CountDownLatch cdl = new CountDownLatch(1);
    private AtomicBoolean win = new AtomicBoolean();

    Print(String string) {
        this.string = string;
    }
    @Override
    public void run() {
        try {
            for (int i = string.length()-1; i >= 0; i--) {
                cb.await();

                if (i != 0) {
                    System.out.print(string.charAt(i) + "-");
                } else {
                    if (win.getAndSet(true)) {
                        cdl.await();
                        System.out.print(string.charAt(i));
                    } else {
                        System.out.print(string.charAt(i) + "-");
                        cdl.countDown();
                    }
                }
            }
        } catch (Throwable ex) {
           ex.printStackTrace();
        }
    }
}

Note that this setup works only for 2 threads.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement