SuperTron
SuperTron

Reputation: 4233

Java Synchronized Object?

I have a class in java that reads UDP packets and puts them in an object (in a basically infinite loop). This object is then accessed in multiple separate threads, but obviously, since it is being filled at the same time, all these getters/setters are in synchronized methods. Problem is, right now these getters have code like this:

public synchronized SomeObject exampleGetter() {
    if(this.isReceiving)
        return oldCachedObject;
    else
        return currentObject;
}

Obviously, that's not quite the best way of doing things, so how should I go about writing methods (lots of different ones) that totally lock the object to one thread at a time and block the others (including the thread that created the object in the first place)? I looked at synchronized blocks, but I am kinda confused as to what effect the "lock object" has, is that the object that has access to the block at that given time? Any advice would be appreciated. Thanks!

Upvotes: 3

Views: 5472

Answers (3)

GETah
GETah

Reputation: 21409

The synchronized keyword synchronizes on the whole object instance not just the setter. I would rather go for a fine grained locking strategy or better... use a thread safe data structure where you store and get the received data. I personally love the BlockingQueue<T> where T is the type of data you receive on the network.

So suppose you are receiving Objects over a socket:

public class ReceivedDataHolder{
    BlockingQueue<Object> dataBuffer = new LinkedBlockingQueue<Object>();
    //...
    public void dataReceived(Object data){
       dataBuffer.offer(data);
    } 

    public Object getReceivedData(){
       return dataBuffer.take();
    }
}

And in your socket you could do this whenever you receive data:

receivedDataHolder.dataReceived(object);

Any thread that wants to get data should do:

receivedDataHolder.getReceivedData();

This latter method call will block the calling thread until there is an element available on the queue (check this out for more details)

I hope this helps

Upvotes: 5

user802421
user802421

Reputation: 7505

Maybe AtomicReference would be suitable for you.

See:
java.util.concurrent.atomic
Java volatile reference vs. AtomicReference

Upvotes: 2

Rajesh Pantula
Rajesh Pantula

Reputation: 10241

All objects in java has something called Intrinsic locks, If any thread wants to do any operation on any object then it needs to acquire the intrinsic lock of that object. it will guarantee that only 1 thread will process your block of code at any given time.

A thread can acquire lock on any object, if that object is not locked by any other thread, if it is locked then the thread will wait till the other thread releases the lock on that object.

if you use synchronized block, your code will be somewhat like this

public void SomeObject exampleGetter() {

synchronized(this)
{


if(this.isReceiving)
        return oldCachedObject;
    else
        return currentObject;


}

In this case when your thread enters the synchronized block, if any other thread is having lock on this object, then it will wait till that thread releases the lock. and if that object is free then your thread will acquire the lock on this object and perform the operation and then release the lock on that object.

for further information on synchronized blocks, methods and intrinsic locks, refer http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

I hope it helped you :)

Upvotes: 0

Related Questions