Search code examples
clojuresynchronization

Clojure - synchronised block


I am trying to send requests to a server. Each request is referenced by an integer. The server will only respond to requests that come in ascending order - that is, if I send request 7 and then request 6, it will disregard request 6. I am working in a multi-threaded environment where several threads can send requests concurrently. In Java, I solved the problem this way:

synchronized(this){
   r = requestId.incrementAndGet();//requestId is an AtomicInteger
   socket.sendRequest(r, other_parameters);
}

In Clojure, I thought about defining request-id as an Atom and doing the following:

(send-request socket (swap! request-id inc) other-parameters)

Does that work or is it possible thread 1 increments the atom, but by the time the send-request function sends the request, thread 2 increments the atom again and somehow contacts the server first? What is the best way to avoid such a scenario?

Thank you,


Solution

  • Clojure's equivalent construct to synchronized is locking, which can be used in basically the same way:

    (locking some-lock
      (let [r (.incrementAndGet requestId)] 
        (.sendRequest socket r other_parameters)))
    

    Where some-lock is the object you're locking on. I'm not sure what you'd want that to be in the absence of this.