All ITKnowledge Source Code Search Tips Advanced Search |

| Mastering Java Threads by Marc Adler and David Herst DDC Publishing, Inc. ISBN: 1562438425 Pub Date: 05/01/99

Search this book:

Previous | Table of Contents | Next

## Chapter 9
Synchronization

Lesson Topics

  • Synchronization: An Introduction
  • Monitors
  • The Scope of a Lock
  • Synchronized Blocks
  • Another Example of Synchronization
  • Deadlock

### Synchronization: An Introduction

Threads have their own stack space and their locally declared variables are private to the thread that created them. However, threads can also access global variables that are stored on the global heap. For example, consider the following (incomplete) applet that retrieves stock prices from an Internet server:

    import java.applet.*;

    class StockApp extends Applet implements Runnable

    {

      public String m_szStockName;

      public double m_dblStockPrice;

      public boolean m_bStockPending = false;

      public PollingThread m_ReutersPollingThread =

          new PollingThread(“Reuters”);

      public PollingThread m_TeleratePollingThread =

          new PollingThread(“Telerate”);

      public void start()

      {

        m_ReutersPollingThread.start();

        m_TeleratePollingThread.start();

      }

      public void run()

      {

         while (m_ReutersPollingThread null &&

                m_TeleratePollingThread != null)

         {

           if (m_bStockPending == true)

           {

              ProcessPendingStock();

           }

           try

           {

              Thread.sleep(1000);

           } catch (InterruptedException e)

         }

      }

      public void ProcessPendingStock()

      {

         /*

            Insert the stock info into a database. . . .

         */

         m_bStockPending = false;

      }

      class PollingThread extends Thread

      {

        public PollingThread(String szName)

        {

           super(szName);

           /*

      We can open a server connection based on the thread name

           */

         }

         public void run()

         {

         for (;;)

         {

            /*

               Read the stock info from the server. . . .

               We block until we get a stock.

            */

            try

            {

               Thread.sleep(1000);

             } catch (InterruptedException e)

             {

             }

             /*

             if (we got a response from the server)

             {

             */

                m_szStockName = “MSFT”;

                m_dblStockPrice = 120.50;

                m_bStockPending = true;

             /*

             }

             */

           }

         }

       }

    }

#### Global Variables

This applet has three global variables that relate to stock prices:

  • public String m_szStockName;
  • public double m_dblStockPrice;
  • public boolean m_bStockPending = false;

The variable m_bStockPending is set to true by one of the server-polling threads when new stock information is retrieved from the server. The thread also sets the two variables that record the stock’s symbol and price.

When the main thread sees that the value of m_bStockPending changes to true, it realizes that there is new stock information which it must insert into some database. It places the values in the database and resets the m_bStockpending variable back to false. It then continues to loop, waiting for a new stock record to appear.

Problems

There are several problems with the previous example:

  1. Q: what happens if the Reuters thread receives information about a stock, but before the main thread can act upon it, another stock record comes in from Reuters? A: the information regarding the second stock would overwrite that regarding the first stock.
  2. Q: what happens if stock information then comes from the Telerate server for a third stock? A: if the main thread has not yet processed the information from Reuters, the information on this third stock will overwrite the information for the second stock.

You can theoretically have the following situation:

    Time       Reuters         Telerate

    T+0        m_szStockName = “MSFT”

    T+1        m_szStockName = “DELL&3148;

    T+2        m_dblStockPrice = 77.375

    T+3        m_dblStockPrice = 120

As you can see, the stock information shows DELL stock with a price of 120.375 per share, which is incorrect.

#### Atomic Operations

What is preferable in the previous example is to have the operation on the stock be atomic. When an operation or a function is considered to be atomic, it is considered to be uninterruptable during its execution.

The problem with this example is that access to the global variables is not synchronized between the three threads that are running in the application.

| If multiple threads are competing for the use of a shared resource, the access to this resource should be synchronized.

#### Producer/Consumer Scenarios

The above code illustrates a typical Producer/Consumer scenario. In this type of scenario, one thread produces data while another thread consumes the data.

Producer Thread

In a User Interface system, one thread might gather mouse events—mouse movements, button presses, and button releases. As the mouse events are gathered, they are placed at the tail of a system queue that is used to monitor user interface events. This is an example of a Producer thread—it produces events.

Consumer Thread

While the User Interface threads are placing data into the system queue, another process is removing events from the head of the queue. This is an example of a Consumer thread—it “eats” data generated by the Producer thread.

Both threads—the producer and the consumer—have to manipulate the system queue. The Producer changes the head and tail pointers of the queue when it inserts data. The Consumer manipulates these pointers when it removes data from the queue.

Synchronizing the Queue

The queue is a valuable system resource whose access must be synchronized. If access is not synchronized to the queue, one thread can be manipulating the head pointer while another thread is manipulating the tail pointer.

### Monitors

A monitor is a synchronization mechanism that has been in use for many years in the world of concurrent programming. A monitor is also known as a mutex lock. A monitor is associated with a specific variable and serves as a lock/release mechanism on that variable.

For example, in the StockApp program created previously in this course, you can place a monitor on the m_bStockPending variable that prohibits more than one thread from accessing the global variables at one time.

Note the following points regarding monitors:

  • Only one thread at a time is allowed to grab a lock.
  • It is not possible for two threads to hold a lock on an object.

Previous | Table of Contents | Next

Copyright © DDC Publishing

Products | Contact Us | About Us | Privacy | Ad Info | Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.