Witscale Test Center

12.4 Thread interaction with wait(), notify() and notifyAll() > 12.4.5 Implementing wait-and-notify in a complex example


12.4.5 Implementing wait-and-notify in a complex example

Now that we know all the essentials of using the wait and notify methods, let us implement the stock application which is inherently wait-and-notify. Following code declares a Stock class. For simplicity it has only bare essential methods.

 

package com.example.stocks;

 

public class Stock {

  private String companyName = “ACME”;

  private float price = 12.56f;

 

  public void modifyPrice(float newPrice) {

    this.price = newPrice;

  }

 

  public float getPrice() {

    return price;

  }

}

 

The stock object’s state will have a company name and price. We wish to analyze the stock price whenever they change. Listing 12.8 has two classes, StockAnalyzer and StockPriceModifier. The StockPriceModifier is a runnable class that keeps randomly changing the stock prices every 10 seconds.  The StockAnalyzer is also a runnable class that remembers a stock price and then waits until the price is modified. Once it gets the notification, it analyses how the price is changed and suggest either to buy or sell the stock.

 

 

 

 




We can test these classes by creating a sample stock object and two thread objects (modifier and analyzer) that operate on the same stock object as:

 

package com.example.threads;

    import com.example.stocks.Stock;

 

    public class ThreadTester {

public static void main(String[] args) {

    

        Stock stock = new Stock();

        StockAnalyzer analyzer = new StockAnalyzer(stock);

        Thread analyzerThread = new Thread(analyzer);

        StockPriceModifier modifier = new StockPriceModifier(stock);

Thread modifierThread = new Thread(modifier);

        

        analyzerThread.start();

        modifierThread.start();

      }

     }

 

 After both the threads started, each one will eventually get the turn to execute. When the analyzerThread starts executing, first it will store the initial stock price. After that it really has nothing to do until the stock’s price is changed. Therefore it decides to wait in stock object’s waiting pool. It does so by calling the stock.wait() method.  While it is waiting, another thread modifierThread may get a chance to execute. This thread calculates a random price from 1 to 100 . It then enters a synchronized block on stock object. Therefore it must get stock object’s lock first. After acquiring that, it modifies the stock’s price and the invokes stock.notify().Since there is only one thread waiting for notification on stock object, the analyzerThread, it will be notified. The modifierThread then releases the stock’s lock and then sleeps for 10 seconds. Meantime analyzerThread might get a chance to execute, it will reacquire the stock object’s lock and access its price stock.getPrice(). It then compares the stock price it initially recorded and performs the stock analysis. Since we have enclosed both threads run methods in an infinite while loop, these threads will continue to execute forever ( as long as JVM is not terminated). The output would be something like this..

 

Waiting for stock to modify...

Notified the waiting thread

Stock price is modified

Buy this stock!

Waiting for stock to modify...

Notified the waiting thread

Stock price is modified

Not good enough to buy.

Waiting for stock to modify...

. . .

 

The output might be different as the stock analysis changes depending on the price. But “Waiting for stock to modify...” will be always followed by “Notified the waiting thread” before doing the stock analysis as the waiting will not be over without the notification.