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.