views:

95

answers:

3

I understand threads in theory, but I have no idea how to implement them in Java.

setup

The circles are supposed to be threads and the rectangles are supposed to be buffers.

I have this all coded but it doesn't work, so I am starting new. My source of confusion comes from the fact that I need this cycle to repeat many times and in this order, but I can't predict what thread will run first. If thread B that relies in data from A runs first, what happens?

Also how can I keep the threads running indefinitely?

+3  A: 
  1. You can programatically start one thread before the other. Then in a simple java program you can be pretty sure which thread will start first (because you decide!)

  2. You can make thread B blocked on empty buffer or queue (depends if your thread B is a retriever and parser)

You can find more literature on this topic by using keywords such as 'concurrency', 'producer' and 'consumer'

Anthony Kong
I would have a synchronized getter that would check the queue for it's size to accomplish what you're suggesting, correct?
tipu
@tipu: Exactly, this is the common pattern used.
ChaosPandion
Starting a thread first does not mean the thread is going to actually do anything first. There is a race condition in that.
Tronic
@Tronic: Agree. That's why I qualified it with 'in a simple java program'. Usually in this homework-like situation, it is repeatable.
Anthony Kong
+6  A: 

You can use Blocking Queues as buffers. They handle everything as far as getting threads to wait for other threads when the queues are empty.

Basically you'll have two classes, one for each thread. So, you'll have something like this.

class PageToRetriveQueue implements Runnable{
   PageBuffer partner;
   BlockingQeueue queue = new LinkedBlockingQueue<Page>();

   public void run(){
     while(true){
       Page p = partner.queue.take();
       for(Link l : p){
         queue.offer(l);
       }
     }
   }
}

class PageBuffer implements Runnable{
   PageToRetriveQueue partner;
   BlockingQeueue queue = new LinkedBlockingQueue<Link>();

   public void run(){
     while(true){
        Link l = partner.queue.take();
        Page p = downloadPage(l);
        queue.offer(p);
     }
   }
}

You'll have to implement the Page, Link, and downloadPage functions. When you start, you'll have to seed one of the queues in order to get started, probably the link queue. It's stylistically bad form to call partner.queue.take() directly, rather you'd have a function that would abstract that. I'm trying to make the code concise and easy to understand here.

Hope that helps!

Chad Okere
Runnable should be capitalized, like all classes and interfaces are conventionally done in Java.
Platinum Azure
Hah, you're right. Fixed that. That's why I always say you're code should look "something like" my examples.
Chad Okere