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.