Search code examples
javasynchronizationclient-serverwait

JAVA synchronize operations between threads using classes


I am currently trying to create sort of a reliable UDP protocol where my server sends packets of 1024 bytes each to my client, when it finishes a send/receive cycle the server waits and the client sends a command over TCP to the server that tells it what packets were not received (I am using the first 2 bytes as a packet id [of type short]), the server than is notified by a remote class and sends the missing packets.

private void waitUntilNotified() {
    synchronized (this) {
        try {
            System.out.println("Waiting..." + new Date());
            waiting = true;
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Stop waiting");
    }
}

public void notifyThis(){
    synchronized (this) {
        if(waiting){
            waiting = false;
            notify();
            System.out.println("Notified " + new Date());
            return;
        }
    }
}

My problem is that sometimes on local testing the command arrives before the server starts waiting, therefore causes it to wait forever.

I was wandering if there was a foolproof way of making sure that even if the command that triggers notifyThis() comes before the server triggers the waitUntilNotified() function it will still notify it and change the waiting status?

If anything is unclear just comment and I'll try to explain it.

TL:DR, I am looking for a way to call notify() only after the server starts to wait() even if the call is made before it starts waiting


Solution

  • It looks to me like what you really need is a higher level concurrency primitive. Here are some possibilities:

    or possibly some kind of Queue or Deque.


    The problem (for us) is that we can't see how you are actually using your wait / notify methods, so it is not clear what you really need.

    But as a general principle it is better in the long term to identify and use an appropriate higher-level concurrency class than to try to implement your own concurrency from the basic building blocks.

    And ... as @D.B notes ... implementing your own "reliable" transport over the top of UDP is reinventing the wheel. TCP is the obvious alternative, and if you are doing this to get "better than TCP" performance, there are other alternatives.