Click to See Complete Forum and Search --> : Java: thread pools


klamath
12-13-2000, 01:14 AM
I'm having a tough time getting my head around the idea of a thread pool (I understand the concept, just not how to implement one in Java). Here's what I've got at the moment.

I have a ServerPool object, which is created and passed an int 'n'. It creates 'n' threads (instances of FooThread, which implements "Thread"), and stores them in a LinkedList (or whatever other data structure). When the dispatch() method of ServerPool is called, it finds the first thread in the pool (in this method, access to the pool is synchronized) -- if it can't find a thread, it creates a new one and puts it in the pool. It then removes the thread from the pool and calls thread.run()

I have implemented everything up to that point. The thread should now execute -- but how can I put the thread back inside ServerPool's LinkedList of available threads after execution? How can I do stuff at the end of Thread.run() -- doesn't the thread terminate automatically when Thread.run() finishes? Basically, I'd like to avoid this behavior -- when Thread.run() finished, I'd like the thread to be placed into the pool again. Am I going about this the wrong way, or have I just missed something obvious?

I'd be happy to provide code if you'd like.

Thanks in advance.

------------------
- Klamath
Get my GnuPG Key Here (http://klamath.dyndns.org/mykey.asc)
Looking for an open source project to contribute to? Check out the Better Bulletin Board (http://bbb.sourceforge.net)

klamath
12-13-2000, 11:19 PM
Never mind - I think I figured this out. If anyone's interested, I'll explain it to you.

------------------
- Klamath
Get my GnuPG Key Here (http://klamath.dyndns.org/mykey.asc)
Looking for an open source project to contribute to? Check out the Better Bulletin Board (http://bbb.sourceforge.net)

Dru Lee Parsec
12-14-2000, 02:15 AM
Hey there klammath:

At the end of the run method you could just get the instance of your data structure and add "this".

Let's say I have a vector in MyThreadPool. And let's say I have a static method in MyThreadPool called getPool() which returns that vector.

At the end of my run method I can just say

((Vector)MyThreadPool.getPool()).addElement(this);

That should add that particular instance of the thread back into your pool. And it'stotally OOP. When your threads are done and are free to be used again they add themselves back into the pool.

Just remember that when you get a thread object out of the pool be sure to actually remove it from the Vector. Don't just use elementAt(int) to get it. If you want to use teh first one in the vector (which you always will) then use elementAt(1) to get a reference to it, then remove that element from the vector with removeElementAt(1);

hungarian
12-14-2000, 01:30 PM
Dru Lee parsec is spot on I think.

Regarding the example Dru, I hope you don't take it the wrong way..
Vector is a deprecated class, use ArrayList instead.
Vector is kept for compatibility with existing programs but ArrayList is more efficient and fixed a number of problems with the Vector class.

------------------
http://homepages.paradise.net.nz/frankkru

Dru Lee Parsec
12-14-2000, 04:05 PM
True, ArrayList is faster better stronger. But Vector is not actually deprecated. There are several API's that still require it. For example: JList(Vector listData) constructor or JList.setListData(Vector listData) exist but no comparable method exist with anArrayList.

But your are absolutly correct that ArrayList is WAY faster. You gotta forgive this old man for his oldstyle programming ways. I started using Java back in 1.1.3 http://www.linuxnewbie.org/ubb/smile.gif

Dru Lee Parsec
12-14-2000, 04:06 PM
Excuse me while I say DUH! to myself. The first item in a vector is accessed with elementAt(0) not elementAt(1)

Geez, you'd think I was a damn Pascal programmer or something.

klamath
12-14-2000, 07:53 PM
Well, I ended up doing it a different way. I think this will work -- but I guess I'll know for sure soon enough http://www.linuxnewbie.org/ubb/biggrin.gif

When ServerPool is contructed, it creates a private ArrayList of "tasks". It then constructs x threads, and passed them the ArrayList of tasks. The constructor for each thread stores the ArrayList locally. Then ServerPool calls run() on each thread. The run() method synchronizes on the ArrayList of tasks. If the ArrayList is empty, the thread calls tasks.wait() -- it will sleep until there's an incoming connection. When a connection is received by the rest of the daemon, it calls pool.dispatch(Socket foo). dispatch() inserts the Socket into the tasks ArrayList, and calls tasks.notify() to wake up the closest waiting thread. The waiting thread awakens, removes the Socket from the ArrayList, and begins talking to the client. And at the top of run() in the threads, there's a while(true) loop - so once a thread has completed a transaction with a given client, it will go back to wait() on the ArrayList of tasks.

There are still a few rough spots to work out (e.g. how do you regulate the number of threads - including spawning extras to handle periods of high load, and killing off these threads once they're no longer needed), but AFAICT, this will work.

------------------
- Klamath
Get my GnuPG Key Here (http://klamath.dyndns.org/mykey.asc)
Looking for an open source project to contribute to? Check out the Better Bulletin Board (http://bbb.sourceforge.net)

[This message has been edited by klamath (edited 14 December 2000).]