Keibosh
Keibosh

Reputation: 1245

Is synchronized needed here

I have a java applet. A class inside that applet is creating a thread to do some work, waiting 30 seconds for that work to complete, if its not completed in 30 secs it sets a Boolean to stop the thread. The wait and Boolean change are in a synchronized block, Is this necessary considering there is no other thread running aside from these 2.

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    synchronized (_sessionThread)
    {
        _sessionThread.wait(30000);
        _sessionThread._stopStartSession = true;
    }

Why couldn't I just do this instead.

    System.out.println("Begin Start Session");
    _sessionThread = new SessionThread();
    _sessionThread.start();

    _sessionThread.wait(30000);
    _sessionThread._stopStartSession = true;

SessionThread run method. Invokes a JNI method to call a dll to open a program window.

public void run()
{
    try
    {
        startExtraSession();
    } 
    catch (Throwable t)
    {
        t.printStackTrace();
    }
        notify();
}


private native void openSessionWindow(String session_file);

private void startExtraSession()
{
    final String method_name = "startExtraSession";

    String title = _sessionInfo._title;
    long hwnd = 0;

    openSessionWindow(_sessionInfo._configFile);

    try
    {
        //Look for a window with the predefined title name...
        while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
        {
            Thread.sleep(500);
    }
    }
    catch(Throwable t)
    {
       t.printStackTrace();
    }
}

1. Is the synchronized really needed?
2. Is there a better way to accomplish this aside from using threads?

Upvotes: 0

Views: 282

Answers (4)

Jeremy Raymond
Jeremy Raymond

Reputation: 6017

If the boolean is the only shared state between the threads, declaring the boolean transient will guarantee that changes to it are seen between the threads as would a synchronization block around access to the boolean.

Upvotes: 0

Romain
Romain

Reputation: 12809

A given thread is required to own a lock on a object to be able to call wait(long) on it. This is achieved by using a synchronized block on the said object.

See J2SE specification on using wait.

Acquiring a lock/monitor in java can be done in various ways:

  • In a synchronized (non-static) method, the thread owns a monitor on the object referenced by this.
  • In a static synchronized method, the thread owns a monitor on the Class<?> descriptor for the class that defines the said method.
  • In a synchronized(x) block, the thread owns a monitor on x.

That lock will be released if:

  • You get outside of the synchronized code block (be it a method, static method, or explicit block).
  • You have called wait() or one of its variations (and you'll re-acquire it just before the method returns).

Both these two lists may omit specific cases but should cover at least a large portion of the typical use cases.

Upvotes: 2

karoberts
karoberts

Reputation: 9938

There's a very simple reason that you need synchronized to call wait

The synchronized makes sure that nobody is calling notify or notifyAll at the same time you're calling wait

For example: Thread 1

synchronized( obj )
{
    triggerActionOnThread2();
    obj.wait();
}

Thread 2 (triggered by triggerActionOnThread2)

    ...
    synchronized( obj )
    {
        obj.notify();
    }

If you don't have the synchronized blocks, then the notify might happen before (or during) the wait, and then the wait misses the notify, and you can hang Thread 1.

Imagine the above blocks of code without the synchronized blocks, and imagine if Thread 2 is executed all the way through the notify before the wait gets called.

BTW, I ask this very question on interviews for Java engineers when the job will involve multithreaded programming.

Upvotes: 0

adrian.tarau
adrian.tarau

Reputation: 3154

Can you please post SessionThread code? You cannot wait if you don't own the lock, so you need synchronized (_sessionThread) to do _sessionThread.wait(30000); Not sure what's with _sessionThread._stopStartSession = true;

Upvotes: 0

Related Questions