0

I was reading @Ashish Lahoti coment in this post: https://stackoverflow.com/a/64077645/15456334 and in "codingnconcepts" web page, I was traying to get a consistent output like:

ping 1
pong 1
ping 2
pong 2
.
.
.
ping 500
pong 500

Always 'ping' and then 'pong' not possible get two same word ping ping or pong pong.

But if I change the time repetitions to 500 and I change the time in "conditionMet.await(2, TimeUnit.SECONDS);" to 0 "conditionMet.await(0, TimeUnit.SECONDS):" I get the next output:

ping 1
pong 1
ping 2
pong 2
.
.
.
Ping 493
Ping 494
Ping 495
Ping 496
Ping 497
Ping 498
Ping 499
Ping 500

As you see in the output exist ping ping repetitions.

I use the wait and notify method And always is OK with the oputput, I have the expected output:

package pingponghilos;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Principal {

    public static void main(String[] args) {

        Runnable ping = new PingPong("PING");
        Runnable pong = new PingPong("pong");

        ExecutorService executorService = Executors.newCachedThreadPool();

        executorService.submit(ping);
        executorService.submit(pong);
        
        System.out.println("hola desde el main");
    }
    
}

class PingPong implements Runnable {

    private static final Object locker = new Object(); // Locker util
    private String name;

    public PingPong(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (locker) {
                System.out.println(name);
                locker.notifyAll();
                try {
                    locker.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

But I am trying to understand the Reentrant lock condition to implement the same as I got with wait() and notify().

Any suggestions? Thanks in advance.

Nervi
  • 13
  • 2

1 Answers1

0

I did this:

package pack_20;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class PingPongTest {

    // Objeto usado para el bloqueo
    public static final ReentrantLock locker = new ReentrantLock(true);

    public static void main(String[] args) {

        Condition c = locker.newCondition();
        PingPong ping = new PingPong("PING", c);
        PingPong pong = new PingPong("pong", c);

        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<Integer> futurePing = executorService.submit(ping);
        Future<Integer> futurePong = executorService.submit(pong);

        System.out.println("Fin del main");
    }

}

class PingPong implements Callable<Integer> {

    private int counter = 0;
    private final String name;
    private final Condition condition; // Condition usada para la instancia de ReentrantLock

    private static AtomicBoolean canSayPing = new AtomicBoolean();

    public PingPong(String name, Condition condition) {
        this.name = name;
        this.condition = condition;
    }

    @Override
    public Integer call() throws Exception {
        for (int i = 1; i <= 500; i++) {
            if (name.equalsIgnoreCase("ping")) {
                sayPing();
            } else {
                sayPong();
            }
            ++counter;
        }
        return counter;
    }

    public void sayPing() throws InterruptedException {

        PingPongTest.locker.lock();

        try {
            while (!canSayPing.get()) {
                condition.await(0, TimeUnit.SECONDS);
            }
            System.out.println(name);
            canSayPing.set(false);
            condition.signal();
        } finally {
            PingPongTest.locker.unlock();
        }

    }

    public void sayPong() throws InterruptedException {

        PingPongTest.locker.lock();

        try {
            while (canSayPing.get()) {
                condition.await(0, TimeUnit.SECONDS);
            }
            System.out.println(name);
            canSayPing.set(true);
            condition.signal();
        } finally {
            PingPongTest.locker.unlock();
        }
    }

}

Output: Always that I was expected.

PING
pong
PING
pong
PING
pong
PING
pong
PING
.
.
.
PING
pong
PING
pong
PING
pong
PING
pong
PING

But I'm think that is not a good solution.

Nervi
  • 13
  • 2