Geesh_SO
Geesh_SO

Reputation: 2206

How to wait and notify between separate objects in Java?

General purpose of program

To read in a bash-pattern and specified location from command line, and find all files matching that pattern in the location but I have to make the program multi-threaded.

General structure of the program

The Problem

I need to be processing matches even whilst the ProcessDirectories class is still working (for efficiency so I don't unnecessarily wait for the list to populate before doing work). To do this I try to: a) make ProcessMatches threads wait() if DirectoryData is empty b) make ProcessDirectories notifyAll() if added a new entry.

The Question :)

Every tutorial I look at is focused on the producer and consumer being in the same object, or dealing with just one data structure. How can I do this when I am using more than one data structure and more than one class for producing and consuming?

Upvotes: 2

Views: 482

Answers (2)

SimonC
SimonC

Reputation: 6718

How about something like:

class Driver(String args)
{
   ProcessDirectories pd = ...
   BlockingQueue<DirectoryData> dirQueue = new LinkedBlockingQueue<DirectoryData>();
   new Thread(new Runnable(){public void run(){pd.addDirs(dirQueue);}}).start();

   ProcessMatches pm = ...
   BlockingQueue<File> fileQueue = new LinkedBlockingQueue<File>();
   new Thread(new Runnable()
     {
       public void run()
       { 
         for (DirectoryData dir = dirQueue.take(); dir != DIR_POISON; dir = dirQueue.take())
         {
           for (File file : dir.getFiles())
           {
             if (pm.matches(data))
               fileQueue.add(file)
           }
         }
         fileQueue.add(FILE_POISON);
       }
     }).start();

   for (File file = fileQueue.take(); file != FILE_POISON; file = fileQueue.take())
   {
     output(file);
   }
}

This is just a rough idea of course. ProcessDirectories.addDirs() would just add DirectoryData objects to the queue. In production you'd want to name the threads. Perhaps use an executor to provide manage threads. Perhaps use some other mechanism to indicate end of processing than a poison message. Also, you might want to reduce the limit on the queue size.

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182761

Have one data structure that's associated with the data the two threads communicate with each other. This can be a queue that has "get data from queue, waiting if empty" and "put data on queue, waiting if full" functions. Those functions should internally call notify and wait on the queue itself and they should be synchronized to that queue.

Upvotes: 1

Related Questions