I am creating my own thread pool and future object which can execute callable interface parallel. Executor provides shutdown method to stop all worker threads from running. If i am creating a thread pool like below how should I implement the shutdown method to stop after all threads have finished execution?
My custom thread pool looks like this
class MyThreadPool implements java.util.concurrent.Executor
{
private final java.util.concurrent.BlockingQueue<Callable> queue;
public MyThreadPool(int numThreads) {
queue = new java.util.concurrent.LinkedBlockingQueue<>();
for (int i=0 ; i<numThreads ; i++) {
new Thread(new Runnable(){
#Override
public void run() {
while(true) {
queue.take().call();
}
}
}).start();
}
}
#Override
public <T> Future<T> submit(Callable<T> callable) {
FutureTask<T> future = new FutureTask(callable);
queue.put(future);
return future;
}
public void shutdown(){ }
}
I couldnt think of a way to keep list of thread and then check if they are idle or not?
You definitely should hold references to the threads you're creating. For instance, set up a field threads of type List<Thread> and add the threads to this list from within the constructor.
Afterwards, you could implement shutdown() with the help of Thread#join():
public void shutdown() {
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) { /* NOP */ }
}
}
Don't forget to replace while (true) with an appropriate condition (which you toggle in shutdown()) and consider using BlockingQueue#poll(long, TimeUnit) rather than take().
EDIT: Something like:
public class MyThreadPool implements Executor {
private List<Thread> threads = new ArrayList<>();
private BlockingDeque<Callable> tasks = new LinkedBlockingDeque<>();
private volatile boolean running = true;
public MyThreadPool(int numberOfThreads) {
for (int i = 0; i < numberOfThreads; i++) {
Thread t = new Thread(() -> {
while (running) {
try {
Callable c = tasks.poll(5L, TimeUnit.SECONDS);
if (c != null) {
c.call();
}
} catch (Exception e) { /* NOP */ }
}
});
t.start();
threads.add(t);
}
}
public void shutdown() {
running = false;
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) { /* NOP */ }
}
}
// ...
}
Related
I am trying to create another thread that processes data while main thread doing some more. Main thread must wait till another thread finishes doStuff with all elements.
And my implementation is pretty straight forward.
Please, take a look at processData and tell me is there some more Java-like way to do it?
I read about Phaser but still can't imagine how to use it or what else can I try?
public class MyClass {
private final NodeQueue queue;
MyClass() {
queue = new NodeQueue();
}
public void processData(Set<String> dataSet) {
// allow transfer
queue.transferEnable()
Thread transfer = new Thread(() -> {
queue.transferData();
})
transfer.start();
// doStuff in another thread
for (String element : dataSet) {
queue.add(element);
// do something more
}
// stop transfer
queue.waitTillEmptyQueue();
queue.transferDisable();
try {
transfer.join();
} catch (...) {
// catch
}
}
public class NodeQueue {
private final ConcurrentLinkedQueue<String> queue;
private boolean transferEnabled;
protected NodeQueue() {
queue = new ConcurrentLinkedQueue<>();
transferEnabled = true;
}
protected void transfer() {
while (!queue.isEmpty()) {
doStuff(queue.poll());
}
}
public void transferData() {
while (tranfserEnabled) {
transfer();
}
}
public synchronized void transferEnable() {
transferEnabled = true;
}
public synchronized void transferDisable() {
transferEnabled = false;
}
public void add(String s) {
queue.add(s);
}
public synchronized void waitTillEmptyQueue() {
while (!queue.isEmpty()) {
if (queue.isEmpty()) {
break;
}
}
}
}
}
Let me copy the Phaser example from my own post
Main thread
// Add producer as a party
Phaser phaser = new Phaser(1);
for (int i=0; i<10000; ++i) {
// Add each task as a party
phaser.register();
queue.put(new Task());
}
// Producer arrived and wait for completion of all tasks
phaser.arriveAndAwaitAdvance();
// At the end, there is only 1 party left which is the producer itself
Consumer
while (true) {
Task task = queue.take();
processTask(task);
// Task completed and remove itself as a party
phaser.arriveAndDeregister();
}
I'm new to Java concurrent package and want to try ExecutorService to control the execution time of a thread.
So for a keep running thread MyThread, I want to use ExecutorService and Future class to stop it after 2 seconds.
public class MyThread extends Thread {
public static int count = 0;
#Override
public void run() {
while (true) {
System.out.println(count++);
}
}
}
public static void main(String[] args) throws IOException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
MyThread thread = new MyThread();
FutureTask<String> futureTask = new FutureTask<String>(thread, "success");
try {
executorService.submit(futureTask).get(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("timeout");
e.printStackTrace();
executorService.shutdownNow();
}
}
However, the thread is still keep printing numbers after 2 seconds. How can I control the thread without changing MyThread class itself?
The main purpose of using ExecutorService is to hide how threads are created, reused and in general managed for the programmer.
Instead of creating MyThread, you need to implement a Runnable:
public class MyRunnable implements Runnable {
private int count = 0;
public void run() {
while (true) {
System.out.println(count++);
}
}
}
And, this would be how to use it:
Future<Void> f = executorService.submit(new MyRunnable());
f.get(2, TimeUnit.SECONDS);
Regarding the termination property in the question, the example Runnable is not a good one, because it does not provide an interruptible task. For example, if a sleep operation is added:
public class MyRunnable implements Runnable {
private int count = 0;
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(count++);
try {
Thread.sleep(0, 1);
} catch (InterruptedException x) {
return;
}
}
}
}
Use returned Future object for control.
I have a pool of worker threads (an ExecutorService).
This pool is used to run shell commands.
I use a shell (/bin/sh) rather than creating a process for the executable directly, because I use shell redirects (>) to write the output directly to disk, without having to pass through the JVM, as well as some other niceties.
Spawning a shell process takes 2-3 milliseconds.
I want each thread to keep a shell process to avoid the overhead of starting it.
How do I allow each thread to own a process?
I am thinking of using a ThreadFactory with thread locals.
class ThreadFactory {
Thread newThread(Runnable r) {
return new Thread(new Runnable() {
Process process = Runtime.getRuntime().exec("/bin/sh")
try {
// store process as thread local here
r.run(); // then r can access thread local
} catch(Exception e) {
try {
process.close();
} catch(Exception e) {
}
throw e;
}
});
}
}
(Alternatively, I could subclass Thread and cast Thread.currentThread() to that class in my Runnable.)
Is this a good approach to solving this problem?
I would keep the Process reference in a ProcessRunnable that continuously executes commands. I think is more clear than using a ThreadLocal and a ThreadFactory. Something like this:
public class ShellCommandExecutor {
private int concurrency = 10;
private int capacity = 100;
private ExecutorService service = Executors.newFixedThreadPool(concurrency);
private BlockingQueue<String> commandsQueue = new LinkedBlockingQueue<>(capacity);
public void start() {
for (int i = 0; i < concurrency; i++)
service.submit(new Runnable() {
#Override
public void run() {
//todo deal with ioexception
Process process = Runtime.getRuntime().exec("/bin/sh");
while (!Thread.currentThread().isInterrupted()) {
try {
String command = commandsQueue.take();
//todo execute commands using the same process per thread
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
}
public void executeCommand(String command) throws InterruptedException {
commandsQueue.put(command);
}
public void shutdown() {
service.shutdownNow();
}
}
EDIT: a solution with thread local that should work easily with cached thread pools:
public class ShellCommandExecutor2 {
//todo limit queue
private ExecutorService service = Executors.newCachedThreadPool();
public void executeCommand(final String command) throws InterruptedException {
service.submit(new Runnable() {
#Override
public void run() {
Process process = ThreadLocalProcessFactory.get();
//todo execute command
}
});
}
public void shutdown() {
service.shutdownNow();
}
private static class ThreadLocalProcessFactory {
private static final ThreadLocal<Process> processThreadLocal =
new ThreadLocal<Process>() {
#Override protected Process initialValue() {
try {
return Runtime.getRuntime().exec("/bin/sh");
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
static Process get() {
return processThreadLocal.get();
}
}
}
In a web server i wrote, each request invokes a list of actions. Some of these actions aren't as critical as others, so I would like to run them in a background thread.
Also, since they aren't that important I don't care if one of them fails seldomly, and I don't want them to take up a thread forever, so other threads would be available to process the next batch.
So, I would like to have a thread pool (e.g.: 10 threads) and hand out a thread to each background task like this. Limit each thread to 1 second, and if it doesn't finish by that time, just kill it, and be available for the next task to come in.
How would I go about doing this ?
So far, this is what I have :
public class AsyncCodeRunner {
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
public void Run(Callable<Void> callableCode, int timeout) {
final int threadTimeout = 10;
Future<Void> callableFuture = executor.submit(callableCode);
try {
callableFuture.get(threadTimeout, TimeUnit.SECONDS);
} catch (Exception e) {
logger.Info("Thread was timed out", e);
}
}
}
And I want to use this class like this :
public void processRequest(RequestObject request) {
// do some important processing
// throw some less important processing to background thread
(new AsyncCodeRunner()).Run(new Callable<Void> () {
#Override
public Void call() throws Exception {
// do something...
return null;
}
}, 1); // 1 second timeout
// return result (without waiting for background task)
return;
}
Will this work like I want it to ? Or how should I change it so it would ?
And what happens if I call Run() but there are no available threads in the threadpool to hand out ?
I think your primary problem with this rather elegant idea is that you are only timing out on the get of the Future, you are not actually aborting the process once it times out, you are just giving up waiting for it. The issue becomes even more complex when you realise that you may even time out when the process hasn't even started - it is just still in the queue.
Perhaps something like this would be effective. It does require two threads but a TimerTask thread should consume very little.
public class RunWithTimeout {
public RunWithTimeout(Runnable r, long timeout) {
// Prepare the thread.
final Thread t = new Thread(r);
// Start the timer.
new Timer(true).schedule(new TimerTask() {
#Override
public void run() {
if (t.isAlive()) {
// Abort the thread.
t.interrupt();
}
}
}, timeout * 1000);
// Start the thread.
t.start();
}
}
class WaitAFewSeconds implements Runnable {
final long seconds;
WaitAFewSeconds(long seconds) {
this.seconds = seconds;
}
#Override
public void run() {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ie) {
System.out.println("WaitAFewSeconds(" + seconds + ") - Interrupted!");
}
}
}
public void test() {
new RunWithTimeout(new WaitAFewSeconds(5), 3);
new RunWithTimeout(new WaitAFewSeconds(3), 5);
}
Here's an alternative that only uses one extra thread.
public class ThreadKiller implements Runnable {
DelayQueue<WaitForDeath> kill = new DelayQueue<>();
private class WaitForDeath implements Delayed {
final Thread t;
final long finish;
public WaitForDeath(Thread t, long wait) {
this.t = t;
this.finish = System.currentTimeMillis() + wait;
}
#Override
public long getDelay(TimeUnit unit) {
return unit.convert(finish - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
#Override
public int compareTo(Delayed o) {
long itsFinish = ((WaitForDeath) o).finish;
return finish < itsFinish ? -1 : finish == itsFinish ? 0 : 1;
}
}
#Override
public void run() {
while (true) {
try {
WaitForDeath t = kill.take();
if (t.t.isAlive()) {
// Interrupt it.
t.t.interrupt();
}
} catch (InterruptedException ex) {
// Not sure what to do here.
}
}
}
public void registerThread(Thread t, long wait) {
// Post it into the delay queue.
kill.add(new WaitForDeath(t, wait));
}
}
public void test() throws InterruptedException {
// Testing the ThreadKiller.
ThreadKiller killer = new ThreadKiller();
Thread killerThread = new Thread(killer);
killerThread.setDaemon(true);
Thread twoSeconds = new Thread(new WaitAFewSeconds(2));
Thread fourSeconds = new Thread(new WaitAFewSeconds(4));
killer.registerThread(twoSeconds, 5000);
killer.registerThread(fourSeconds, 3000);
killerThread.start();
twoSeconds.start();
fourSeconds.start();
System.out.println("Waiting");
Thread.sleep(10 * 1000);
System.out.println("Finished");
killerThread.interrupt();
}
You need to start timer when the thread runs. Then no thread in waiting state will be killed. Here is the sample from this thread:
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PoolTest {
class TimeOutTask extends TimerTask {
Thread t;
TimeOutTask(Thread t) {
this.t = t;
}
public void run() {
if (t != null && t.isAlive()) {
t.interrupt();
}
}
}
class MyRunnable implements Runnable {
Timer timer = new Timer(true);
public void run() {
timer.schedule(new TimeOutTask(Thread.currentThread()), 1000);
try {
System.out.println("MyRunnable...");
Thread.sleep(10000);
} catch (InterruptedException ie) {
System.out.println("MyRunnable error...");
ie.printStackTrace();
}
}
}
public static void main(String args[]) {
new PoolTest();
}
public PoolTest() {
try {
ExecutorService pe = Executors.newFixedThreadPool(3);
pe.execute(new MyRunnable());
} catch (Exception e) {
e.printStackTrace();
}
}
}
So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}