Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / August 2005

Tip: Looking for answers? Try searching our database.

Oldie Synchronize Question from Newbie

Thread view: 
Russ - 27 Aug 2005 20:08 GMT
Hi All,
As a relative Java newcomer I have taken over -on an amateur level-
development of an applet that is forever stuck in Java 1 for
technical reasons, but still has uses in art and education :)
I preface my question with this fact, so folks understand why there
are some archaic appoaches used in the code examples.
My question is in regard to when a method needs to be "synchronized"
I did not write the following snippets of code and have some
reservations about them.

The following method can possibly be called by two or more different
threads at the same time:

 public  void sendMessage( Message msg ) throws IOException {
   if( msg.getType() == ControlMessage.TYPE ){
     sendRawMessage( msg );
   }
   else {
        msgBuffer.put( msg );
   }
 }

By all rights then, shouldn't "sendMessage" be synchronized?

i.e.: public synchronized void sendMessage( Message msg ) ....

What makes the question tricky and creates reservations (in my mind
anyway)is that the method "sendRawMessage" has a synchronized
DataOutputStream ("out") and the "put" method of inner class
"msgBuffer" uses a synchronized Vector
class (I did say it was archaic!) as a buffer:

  protected void sendRawMessage( Message msg ) throws IOException {
   synchronized( out ){
     out.writeInt( msg.getType());
     msg.write(out);
     out.flush();
   }
 }

  public void put( Message msg ){
     synchronized( buffer ){
       if( !buffer.isEmpty()){
         Enumeration list = buffer.elements();
         RealTimeMessage rt, help;
         rt = (RealTimeMessage) msg;
         while( list.hasMoreElements()) {
           help = (RealTimeMessage) list.nextElement();
           if( help.tag.equals( rt.tag ) && help.data.getType() ==
rt.data.getType()){
             buffer.removeElement( help );
             break;
           }
         }
       }
       buffer.addElement( msg );
       buffer.notify();
     }
   }

The "msgBuffer" inner class also has a thread that then
delivers the synchronized Vector's (buffer) contents back
to the method "sendRawMessage" after sorting :

public void run(){
     Message msg;
     while( Thread.currentThread() == runner ){
       try{
         if(!buffer.isEmpty()){
           synchronized( buffer ){
             msg =(Message) buffer.firstElement();
             buffer.removeElementAt(0);
           }
           sendRawMessage( msg );
         }
         else {
           synchronized( buffer ){
              buffer.wait();
           }
         }
catches a bunch of exceptions .....

Now since "sendRawMessage" method is being called by two seperate
threads ( diversion "msgBuffer" and original "sendMessage" )
shouldn't it be synchronized as well?

Or am I simply off base here, because since both Vector and
DataOutputStream classes are synchronized the methods containing
them don't need to be?

Thanx
Russ Kinter
Thomas Hawtin - 27 Aug 2005 20:58 GMT
> [...]
> My question is in regard to when a method needs to be "synchronized"
[quoted text clipped - 14 lines]
>
> By all rights then, shouldn't "sendMessage" be synchronized?

It does not appear to be anything that requires synchronisation.
Presumably msgBuffer is fixed. It doesn't access anything mutable that
might be shared. Two threads passing through the method (or other blocks
synchronised on the instance) at the same time will notice each other.

>    protected void sendRawMessage( Message msg ) throws IOException {
>     synchronized( out ){
[quoted text clipped - 24 lines]
>             }
>           }

Here be race conditions. Almost always, wait should be called from
within a while loop. To synchronised blocks like that are a good sign of
trouble.

        for (;;) {
            Message message;
            synchronized (buffer) {
                for (;;) {
                    if (Thread.currentThread() != runner) {
                        return;
                    }
                    if(!buffer.isEmpty()) {
                        break;
                    }
                    buffer.wait();
                }
                message = (Message)buffer.firstElement();
                buffer.removeElementAt(0);
            }
            sendRawMessage(message);
        }

(Usual disclaimer.)

> Now since "sendRawMessage" method is being called by two seperate
> threads ( diversion "msgBuffer" and original "sendMessage" )
> shouldn't it be synchronized as well?

What are you trying to protect?

> Or am I simply off base here, because since both Vector and
> DataOutputStream classes are synchronized the methods containing
> them don't need to be?

In general you need to group together operations into a logical task.
Your operations seem to do that on out and buffer.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.