deniz
deniz

Reputation: 2567

Is Synchronized Blocking?

In java, I have 2 threads in my client, one is controlling the network flow, the other one is processing the messages, draws game etc. What I am trying to do is when a packet comes, the network thread will call messageReceived method of the game thread, containing the message as parameter. Will it block networking thread if i make the function messageReceived as synchronized and there are 2 packets sequentally come before messageReceived function ends, or it doesn't block and my packet is lost because network thread couldn't call messageReceived function which is already being used by game thread ?

Upvotes: 3

Views: 1822

Answers (6)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

Yes, synchronized blocks a thread if the implicit lock has already locked by another thread. But there is a non-blocking alternative - java.util.concurrent.locks.Lock that is more flexible

Lock.tryLock()
  • acquires the lock only if it is free at the time of invocation

and

Lock.tryLock(long time, TimeUnit unit)
  • acquires the lock if it is free within the given waiting time and the current thread has not been interrupted.

Upvotes: 0

ug_
ug_

Reputation: 11440

Its easy to conceptualize but im more of a visual person. Heres a bit of code that helped me long ago understand what excatly syncorized did and how it worked. If you watch the output you will see when you add the synchronized attribute to the print function that you never see As and Bs mixed. but when you remove it you will see a much different output. It should be straight forward once you see it.

public class Main {
    public static void main(String[] args) {
        (new ThreadA()).start();
        (new ThreadB()).start();
    }

    // try it with removing the synchronized:  public static void print(String str) {
    public static synchronized void print(String str) {
        for(int i = 0; i<100; i++)
            System.out.print(str);
        System.out.println();
    }

    public static class ThreadA extends Thread {
        public void run() {
            while(true) {
                print("A");
            }
        }
    }
    public static class ThreadB extends Thread {
        public void run() {
            while(true) {
                print("B");
            }
        }
    }
}

Upvotes: 1

Deadron
Deadron

Reputation: 5279

It sounds like you are attempting to solve a problem that could be easily avoided if you used a more mainstream design pattern such as the Observer Pattern. http://en.wikipedia.org/wiki/Observer_pattern

Upvotes: 0

Juned Ahsan
Juned Ahsan

Reputation: 68715

If a thread calls a synchronized method in a class, all the other threads will be blocked to call any synchronized method in that class because the object lock is not available. If your messageReceived is not working on any shared resource then keep it non-synchronized. In case it is using some shared resource then try to minimized the synchronized code by wrapping that code in synchronized block.

Upvotes: 0

roylaurie
roylaurie

Reputation: 1858

Correct, you're blocking on the IO thread. You want to only do light work on messageReceived() because of that ... perhaps only queue the message in some sort of FIFO for the processing thread to work on later. Your sync blocks should have as small a footprint as possible.

Upvotes: 0

greedybuddha
greedybuddha

Reputation: 7507

When you use the synchronized keyword to sync a code section, then when another thread comes in that wants access to that section it will block until it can get access.

Upvotes: 2

Related Questions