Does anyone know the order of execution in the ExecutorService class?
I’m trying to do some thread pooling but I want it stack(last in first out) based and ExecutorService seems to be queue(first in first out) based in my application.
Does anyone know how to change it without rewriting it? I’m not really finding anything on Google.
Pass your own BlockingQueue to the ThreadPoolExecutor constructor
Awesome found what I want:
private transient final ExecutorService threadPool= new ThreadPoolExecutor(3, 10,10, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
Under my tests that doesn’t seem to be working either. Ideas on why?
I left my crystall ball at the office last friday, so could you please forgive me to ask you what exactly doesn’t work?
Forgive me, but isn’t a LinkedBlockingDeque or other BlockingQueue just another queue structure, so it will still use FIFO behavior?
Sure, but you can invoke addFirst() instead of add().
[quote]I left my crystall ball at the office last friday, so could you please forgive me to ask you what exactly doesn’t work?
[/quote]
Sorry I mean’t it wasn’t LIFO.
[quote]Sure, but you can invoke addFirst() instead of add().
[/quote]
How do I get the ExecutorService to do this?
I guess you could create a LIFO wrapper to the Deque. There’s Collections.asLifoQueue(), but that returns a Queue not a BlockingQueue.
Or extend ThreadPoolExecutor and override execute() or submit()?
AFAIK, you can simple push your tasks (to the other side) in the queue yourself, ExecutorService will pop the queue automatically.
[quote]AFAIK, you can simple push your tasks (to the other side) in the queue yourself, ExecutorService will pop the queue automatically.
[/quote]
Tried that but that didn’t seem to work.
[quote]Or extend ThreadPoolExecutor and override execute() or submit()?
[/quote]
That looked quite hard to get right by looking at the ThreadPoolExecutor source code.
[quote]I guess you could create a LIFO wrapper to the Deque.
[/quote]
This was the easiest option. Thanks.
If anyone else want’s to use the hacked up wrapper code :
package util;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
* LIFO BlockingQueue to be used with the ExecutorService.
* @author Daniel
* @param <T>
*/
public class LinkedBlockingStack<T> implements BlockingQueue<T>{
private final LinkedBlockingDeque<T> stack = new LinkedBlockingDeque<T>();
@Override
public T remove() {
return stack.remove();
}
@Override
public T poll() {
return stack.poll();
}
@Override
public T element() {
return stack.element();
}
@Override
public T peek() {
return stack.peek();
}
@Override
public int size() {
return stack.size();
}
@Override
public boolean isEmpty() {
return stack.isEmpty();
}
@Override
public Iterator<T> iterator() {
return stack.iterator();
}
@Override
public Object[] toArray() {
return stack.toArray();
}
@Override
public <S> S[] toArray(final S[] a) {
return stack.toArray(a);
}
@Override
public boolean containsAll(final Collection<?> c) {
return stack.containsAll(c);
}
@Override
public boolean addAll(final Collection<? extends T> c) {
return stack.addAll(c);
}
@Override
public boolean removeAll(final Collection<?> c) {
return stack.removeAll(c);
}
@Override
public boolean retainAll(final Collection<?> c) {
return stack.removeAll(c);
}
@Override
public void clear() {
stack.clear();
}
@Override
public boolean add(final T e) {
return stack.offerFirst(e); //Used offerFirst instead of add.
}
@Override
public boolean offer(final T e) {
return stack.offerFirst(e); //Used offerFirst instead of offer.
}
@Override
public void put(final T e) throws InterruptedException {
stack.put(e);
}
@Override
public boolean offer(final T e, final long timeout, final TimeUnit unit)
throws InterruptedException {
return stack.offerLast(e, timeout, unit);
}
@Override
public T take() throws InterruptedException {
return stack.take();
}
@Override
public T poll(final long timeout, final TimeUnit unit)
throws InterruptedException {
return stack.poll();
}
@Override
public int remainingCapacity() {
return stack.remainingCapacity();
}
@Override
public boolean remove(final Object o) {
return stack.remove(o);
}
@Override
public boolean contains(final Object o) {
return stack.contains(o);
}
@Override
public int drainTo(final Collection<? super T> c) {
return stack.drainTo(c);
}
@Override
public int drainTo(final Collection<? super T> c, final int maxElements) {
return stack.drainTo(c, maxElements);
}
}
I’ve just copy and pasted that to a file in case it’s of use in the future. I think I’ve found my new approach to coding the boring stuff - I’m just going to suggest them on here and wait a few days for them to appear! ;D
[quote]I’ve just copy and pasted that to a file in case it’s of use in the future. I think I’ve found my new approach to coding the boring stuff - I’m just going to suggest them on here and wait a few days for them to appear!
[/quote]
Hehe. It helped my application a lot. I would of thought a stacked based thread pool would be used more but couldn’t find anything on Google.
I have a LIFO executor service hacked up in my private libs. I’m not certain it works as expected (no unit tests ;D, but i use in my stupid projects).
It is somewhere inside this:
http://code.google.com/p/bookjar-utils/source/browse/BookJar-utils/src/util/threads/Threads.java