• Advertisement

Archived

This topic is now archived and is closed to further replies.

[java] Using synchronized

This topic is 5548 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I''m doing a multi-threaded program and ran into a doubt. On some points, I need to access files. To prevent "collisions" (having two threads accessing the same file at the same time), I''m planning on creating a "control function" that''ll be synchronized (therefore, only one object will be able to access it at the same time). This function will then call the respective sub-functions that''ll do the job. This should solve the access problem. My question is: if I make a function overload with synchronized, will the program run only one of these functions or will it treat each of the functions differently? For example: I have a fileaccess(int x) and fileaccess(int x, int y), both synchronized. If fileaccess(int x) is running, can fileaccess(int x, int y) run at the same time? Or "blocking" one will block both of them? Thanks. Pedro Amaro (http://pedroamaro.pt.vu)

Share this post


Link to post
Share on other sites
Advertisement
Print out a message before, during and after each function, waiting for a random amount of time in each. That will let you figure out what happens.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | Free C++ IDE. ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Boost C++ Lib ]


[edited by - Fruny on December 7, 2002 3:37:58 PM]

Share this post


Link to post
Share on other sites
quote:
I have a fileaccess(int x) and fileaccess(int x, int y), both synchronized. If fileaccess(int x) is running, can fileaccess(int x, int y) run at the same time? Or "blocking" one will block both of them?

Java synchronizes methods and blocks based on which object the operation is locked on. Methods that are synchronized by placing the synchronized keyword in the method declaration are locked on the object that the method is called on. So if the two methods are in the same object then running one of them will block access to both of them.

To break up the synchronization of different methods inside on object (to make the methods use different objects as locks), you can use synchronization blocks inside the method instead of putting synchronized in the method declaration, like this:


      
class SomeClass {
Object lockA = new Object();
Object lockB = new Object();

public void methodA() {
synchronized(lockA) { // block uses lockA as a synchronization lock

// Method code here

}
}

public void methodB() {
synchronized(lockB) { // block uses lockB as a synchronization lock

// Method code here

}
}
}


[edited by - HenryAPe on December 7, 2002 4:44:18 PM]

Share this post


Link to post
Share on other sites
Hmmm... what I want is to make sure that two objects of the same class can''t access the same method at the same time. It doesn''t matter which objects are, as long as they belong to the same class.

Anyone knows this for sure or should I follow Fruny''s suggestion?

Pedro Amaro (http://pedroamaro.pt.vu)

Share this post


Link to post
Share on other sites
Declare the lock object fields static and the same object will be used by all instances of the class containing the fields (you might also want to make them final to ensure that they do not change).

[edited by - HenryAPe on December 7, 2002 6:11:21 PM]

Share this post


Link to post
Share on other sites
Hmm,

pamaro>
Declaring both of those methods synchronized will suffice to keep multiple threads accessing the functionality contained within those methods concurrently.
So if you by design have just one instance of the controller class (it''s a singleton), then making all critical methods synchronized is enough to prevent the "collisions".

P.S.: Thinking in JAVA contains a nice intro into threads. Definitely worth reading.

P.P.S.: Thread creation tend to be rather expensive, so avoid excessive thread creation and rather reuse existing threads.

have fun

Petr Stedry

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just to answer your question more directly, you can take a lock out on a class using the synchronized keyword.

synchronized((new ClassToLock()).getClass())
{
/* Mutex on Class in here */
}

Share this post


Link to post
Share on other sites
quote:
synchronized((new ClassToLock()).getClass())


A better solution is to do synchronized(ClassToLock.class) instead, which does the same thing but avoids the object allocation that takes extra time and will require garbage collection.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Nice! I do like that, always wondered how you got around that problem. I should really poke my nose deeper into the Java spec.

Share this post


Link to post
Share on other sites
Yes, it is quite hard to find in the spec I think, I got it from other programmers.

I would still recommend using a specially designated protected static final lock object though when using block synchronizaion since that gives you a designated lock that you can also use in overloaded methods in derived classes that need to be synchronized with methods in the superclass.

[edited by - HenryAPe on December 12, 2002 7:24:59 AM]

Share this post


Link to post
Share on other sites
Just a final post to mention the solution I ended up using (it might be useful for someone else having the same problem).

I sort of followed Henry''s static suggestion with a small little twist. The Worker class (which was the "thread" class) contained a static synchronized method called "file_access_control". I did something quite simple: after checking the command line and noticing which was the command given by the user, I would use that function to call the appropriate method to take care of that command ("send_message", "read_message", etc). This way, I made sure that it was impossible for two different threads to access the same file (for example, if one user was deleting a message and another user was, at the same time, sending him a message). It''s pretty much a basic "semaphore" implementation, but it worked nice .

Thanks for the input!

Pedro Amaro
Play Java games at http://pedroamaro.pt.vu

Share this post


Link to post
Share on other sites

  • Advertisement