I\'m trying to create a simple queue with Java Thread that would allow a loop, say a for loop with 10 iterations, to iterate n (< 10) threads at a time and wait until tho
see java.util.concurrent and especially Executors and ExecutorService
Use the Executors, as recommended by the others. However, if you want the fun of doing it yourself, try something like this. (Take care. I wrote it in Notepad and there's some Exceptions you'll need to catch even if I got everything else right. Notepad's poor at catching coding errors.) This is more a concept than an actual solution to anything, but the idea could be generally useful.
private ConcurrentLinkedQueue<MyThread> tQueue =
new ConcurrentLinkedQueue<MyThread>();
class MyThread extends Thread {
public Runnable doSomething;
public void run() {
// Do the real work.
doSomething();
// Clean up and make MyThread available again.
tQueue.add( mythread );
// Might be able to avoid this synch with clever code.
// (Don't synch if you know no one's waiting.)
// (But do that later. Much later.)
synchronized (tQueue) {
// Tell them the queue is no longer empty.
tQueue.notifyAll();
}
}
}
Elsewhere:
// Put ten MyThreads in tQueue.
for (int i = 0; i < 10; i++) tQueue.add( new MyThread() );
// Main Loop. Runs ten threads endlessly.
for (;;) {
MyThread t = tQueue.poll();
if (t == null) {
// Queue empty. Sleep till someone tells us it's not.
do {
// There's a try-catch combo missing here.
synchonized( tQueue ) { tQueue.wait() };
t = tQueue.poll();
} while (t == null) break; // Watch for fake alert!
}
t.doSomething = do_some_work;
t.start();
}
Also, note the clever use of ConcurrentLinkedQueue. You could use something else like ArrayList or LinkedList, but you'd need to synchronize them.
Crate Logger.class
:
public class Logger extends Thread {
List<String> queue = new ArrayList<String>();
private final int MAX_QUEUE_SIZE = 20;
private final int MAX_THREAD_COUNT = 10;
@Override
public void start() {
super.start();
Runnable task = new Runnable() {
@Override
public void run() {
while (true) {
String message = pullMessage();
Log.d(Thread.currentThread().getName(), message);
// Do another processing
}
}
};
// Create a Group of Threads for processing
for (int i = 0; i < MAX_THREAD_COUNT; i++) {
new Thread(task).start();
}
}
// Pulls a message from the queue
// Only returns when a new message is retrieves
// from the queue.
private synchronized String pullMessage() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
}
}
return queue.remove(0);
}
// Push a new message to the tail of the queue if
// the queue has available positions
public synchronized void pushMessage(String logMsg) {
if (queue.size() < MAX_QUEUE_SIZE) {
queue.add(logMsg);
notifyAll();
}
}
}
Then insert bellow code in your main class :
Logger logger =new Logger();
logger.start();
for ( int i=0; i< 10 ; i++) {
logger.pushMessage(" DATE : "+"Log Message #"+i);
}
I would use the Java 5 Executors instead of rolling your own. Something like the following:
ExecutorService service = Executors.newFixedThreadPool(10);
// now submit our jobs
service.submit(new Runnable() {
public void run() {
do_some_work();
}
});
// you can submit any number of jobs and the 10 threads will work on them
// in order
...
// when no more to submit, call shutdown, submitted jobs will continue to run
service.shutdown();
// now wait for the jobs to finish
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);