Friday, December 03, 2004

statics and threads in java...

I was asked by someone recently about the evils of static members. I talked about lack of state in these variables, overriding being not possible, etc. But the other person asked me how statics were evil in the context of Threads. I told him that if a static method is synchronized, then only one static synchronized method in the class will be accessible at any point of time to the threads. He was still not convinced though. He told me that if a static synchronized method is accessed by a thread, then even non-static synchronized methods are not available to other threads.

I was surprised. My understanding of threads was that, if a method is synchronized, then the monitor of "this" has to be obtained by the calling thread before it enters that method. However, if the method is static then the monitor of the Class instance (this.class) has to be obtained. So if there were two threads and one of them is accessing a non-static synchronized method, and the other is accessing a static synchronized method, both threads should comfortably have access to those methods.

I tried out a sample. Here's the code for the same. Try out this sample and see for yourself.
Correct me if my understanding of threads is wrong.







public class StaticsAndThreadsTest
{
  public static void main(String[] args)
  {
      class Runner implements Runnable
      {
        TestObject obj = new TestObject("TestObject");
        private int code;
        public Runner(int i)
        {
          this.code = i;
        }

        public void run()
        {
          if(code%!= 0)
          {
            TestObject.staticallyDoingSomething();
            TestObject.staticallyDoingSomething();
          }
          else
          {
            obj.doSomething();
            obj.doSomething();
          }
        }
      };

    for(int i=0; i<10; i++)
    {
      Thread thrd = new Thread(new Runner(i));
      thrd.start();
    }
  }
}

class TestObject
{
  private String name;
  public TestObject(String name)
  {
    this.name = name;
  }

  public synchronized void doSomething()
  {
    System.out.println("Thread " + Thread.currentThread().getName() ": doing something.");
  }

  public static synchronized void staticallyDoingSomething()
  {
    try
    {
      System.out.println("Thread " + Thread.currentThread().getName() ": statically doing something.");
      Thread.sleep(1000);
    }
    catch(InterruptedException iex)
    {
    }

  }
}


3 Comments:

At 3:49 PM, Blogger sundar said...

now that i understand what you were talking abt i agree with you. the code also supports you through output like this:
Thread Thread-3: statically doing something.
Thread Thread-5: statically doing something.
Thread Thread-7: statically doing something.
Thread Thread-9: statically doing something.

 
At 8:53 AM, Anonymous Anonymous said...

Hi Guys

I am confused. I see all the non-static method invocations first and then the static method invocations. So, now which is the true statement? Ur thoughts or the one of your friend's?

Thread Thread-0: doing something.
Thread Thread-0: doing something.
Thread Thread-1: statically doing something.
Thread Thread-2: doing something.
Thread Thread-2: doing something.
Thread Thread-4: doing something.
Thread Thread-4: doing something.
Thread Thread-6: doing something.
Thread Thread-6: doing something.
Thread Thread-8: doing something.
Thread Thread-8: doing something.
Thread Thread-3: statically doing something.
Thread Thread-5: statically doing something.
Thread Thread-7: statically doing something.
Thread Thread-9: statically doing something.
Thread Thread-1: statically doing something.
Thread Thread-3: statically doing something.
Thread Thread-5: statically doing something.
Thread Thread-7: statically doing something.
Thread Thread-9: statically doing something.

 
At 4:28 PM, Blogger Sagar said...

If the method is static or if the same object calls the method again would synchronize actually wait for the previous call to complete before the next method is run again by some other call....

For differnt objects (here a new TestObject is created for every thread) the synchronize is not of much use...

 

Post a Comment

<< Home