I have a class which uses the executor service to run a task concurrently.
Code:
class SomeClass{
private static ExecutorService taskThread = Executors.newFixedThreadPool(1, new ThreadFactory() {
private int threadCount = 0;
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
taskThread.shutdown();
}
});
}
doSomeTask()
{
DocumentUploader callable = new DocumentUploader(randomID,fileLoc);
FutureTask<String> task1 = new FutureTask<String>(callable);
taskThread.execute(task1);
}
someFunctionforWait(){
//what here..???
}
I have another class name SomeOtherClass which will access the modifications / calculations done by task1 thread. So I need to wait for the thread to complete, So how can I wait for task1 to complete . What I intend to do is to call someFunctionforWait() from the class SomeOtherClass to check if the thread has completed and then start to do its task.
How do I do that.
You could use Futures, or if you want to stick with the ExecutorService, just wait for taskThread.shutdown() and taskThread.awaitTermination(); you could put those statements into your someFunctionforWait() and continue execution after that. Here is a simplified example based on your code:
public class SomeClass {
private ExecutorService taskThread = Executors.newFixedThreadPool(1);
private List<Future<String>> futures = new ArrayList<Future<String>>();
void doSomeTask() {
FutureTask<String> task1 = new FutureTask<String>(new Callable<String>() {
public String call() throws Exception {
System.out.println("thread executing");
Thread.sleep(1000);
return Thread.currentThread().toString();
}
});
taskThread.execute(task1);
futures.add(task1);
};
public void someFunctionforWait() throws InterruptedException, ExecutionException{
taskThread.shutdown();
taskThread.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("joined");
}
public void someFunctionforWaitAlternative() throws InterruptedException, ExecutionException{
for(Future<String> future : futures) {
System.out.println("future val: " + future.get());
}
System.out.println("joined");
}
public static void main(String[] args) throws Exception {
SomeClass c = new SomeClass();
c.doSomeTask();
c.someFunctionforWait();
//c.someFunctionforWaitAlternative();
}
}
Create a Future through taskThread and call get() on it. It will block until the Future is completed:
Future<String> f = taskThread.submit(callable); // concurrent operation
String result = f.get(); // blocks until f completes
// use result
Related
I am working with a init() that need to be synchronise. But I have to run some set of instructions in init() which has to execute on main thread. So I created a runnable to add this instruction. And those instructions has some async calls.
So I am exploring efficient ways to block the init() untill all the instructions completes successfully.
Static void init() {
new Handler(context.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// doing some async calls
}
}
}
You need to synchronize the init() method and then use CompletionService to wait for Future to complete. Like so:
public synchronized void init() throws InterruptedException {
Executor executor = Executors.newFixedThreadPool(4);
CompletionService<String> completionService = new ExecutorCompletionService<String>(executor);
// 4 tasks
for (int i = 0; i < 4; i++) {
completionService.submit(new Callable<String>() {
public String call() {
return "i am an async task finished";
}
});
}
int received = 0;
boolean errors = false;
while (received < 4 && !errors) {
Future<String> resultFuture = completionService.take(); // blocks if none available
try {
String result = resultFuture.get();
System.out.println(result);
received++;
} catch (Exception e) {
errors = true;
/// some acceptable error handling;
}
}
}
I have taken the code from this thread and adopted it for your needs. Don't forget to handle InterruptedException properly like described here.
My code looks like this:
public class ExceptionTest {
public static Logger log = LoggerFactory.getLogger(ExceptionTest.class);
public final static ThreadFactory factory = new ThreadFactory() {
#Override
public Thread newThread(Runnable target) {
final Thread thread = new Thread(target);
log.debug("Creating new worker thread");
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
log.error("Uncaught Exception", e);
}
});
return thread;
}
};
final static ExecutorService executor = Executors.newCachedThreadPool(factory);
public static void main(String[] args) {
executor.execute(new Runnable() {
#Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName());
int i = 1;
int j = 0;
System.out.println(i / j);
}
}
});
}
}
The console only print the message one time. This means the thread has died. Is there any other way to prevent thread death (except try catch block, this is much repeated code).
No, you can not achieve this without using try...catch block, see jls:
If no catch clause that can handle an exception can be found, then the
current thread (the thread that encountered the exception) is
terminated.
And, I do not think the termination of threads in a cached thread pool is a problem, since next time you submit a new task, a new thread will be created to handle it.
If it really matters, and you do not want repeated code, you can write a wrapper class like this:
public class WrapperRunnable implements Runnable {
Runnable runnable;
public WrapperRunnable(Runnable runnable) {
this.runnable = runnable;
}
#Override
public void run() {
while (true) {
try {
runnable.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And submit WrapperRunnable to executor:
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println(Thread.currentThread().getName());
int i = 1;
int j = 0;
System.out.println(i / j);
}
};
WrapperRunnable wrapperRunnable = new WrapperRunnable(runnable);
executor.execute(wrapperRunnable);
I don't have previous experience with JAVA's concurrency, but ever done the same in C#.
My task
To create a "worker" class for easy multi-threading (creating continuous threads) managing in my applications.
what i want to have as result(usage example):
Worker worker = new Worker();
worker.threadCount = 10;
worker.doWork(myMethod);
worker.Stop();
to be able to use it in any class in my app, accepting 'void' methods as 'worker.doWork(myMethod);' argument.
What did i done from my researches on question:
class Worker
package commons.Threading;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
public class Worker {
static Boolean IsRunning = true;
public static int threadCount = 2;
static ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(threadCount);
public void doWork(**argument method**) throws IOException, InterruptedException {
while (IsRunning) {
threadPool.submit(new Runnable() {
**argument method**
});
Thread.sleep(1000);
}
}
public static void Stop(){
IsRunning = false;
threadPool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
threadPool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
threadPool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}
ErrorReportingThreadPoolExecutor
package commons.Threading;
import java.util.concurrent.*;
public class ErrorReportingThreadPoolExecutor extends ThreadPoolExecutor {
public ErrorReportingThreadPoolExecutor(int nThreads) {
super(nThreads, nThreads,
0, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
#Override
protected void afterExecute(Runnable task, Throwable thrown) {
super.afterExecute(task, thrown);
if (thrown != null) {
// an unexpected exception happened inside ThreadPoolExecutor
thrown.printStackTrace();
}
if (task instanceof Future<?>) {
// try getting result
// if an exception happened in the job, it'll be thrown here
try {
Object result = ((Future<?>)task).get();
} catch (CancellationException e) {
// the job get canceled (may happen at any state)
e.printStackTrace();
} catch (ExecutionException e) {
// some uncaught exception happened during execution
e.printStackTrace();
} catch (InterruptedException e) {
// current thread is interrupted
// ignore, just re-throw
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) throws InterruptedException {
// replace
// ExecutorService threadPool = Executors.newFixedThreadPool(2);
// with
ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(2);
while (true) {
threadPool.submit(new Runnable() {
#Override public void run() {
System.out.println("Job is running...");
if (Math.random() < 0.5) {
int q = 1 / 0;
}
System.out.println("Job finished.");
}
});
Thread.sleep(1000);
}
}
}
So, the question is - how do i pass 'void' method from outside class here threadPool.submit(new Runnable() { here });
You could pass the Runnable itself is a parameter,
public void doWork(Runnable runnable) throws IOException, InterruptedException {
while (IsRunning) {
threadPool.submit(runnable);
Thread.sleep(1000);
}
}
Runnable is a functional interface,it has a single method run that takes no-param and returns void, and hence you can use it as a function.
Runnable runnable = new Runnable(){
public void run(){
// do work
}
};
doWork(runnable);
You can express it more concisely if you are on Java 1.8
Runnable runnable = ()->{/**do work*/};
doWork(runnable);
I have a worker threadpool set up that executes a bit of work which I want to log in a central place.
To be more precise, I've extended the Thread class into a worker class, which checks the status of a concurrent queue. If it's empty, then it waits. As elements are added by another thread, notify() wakes the workers. Once they've completed the task, they wait for the next element in the queue.
What's the best practice to have each of the threads report their status at the end of each of their tasks?
public class PoolWorker extends Thread {
public ConcurrentLinkedQueue<Device> q;
public PoolWorker(ConcurrentLinkedQueue<Device> q, String type){
this.q = q;
this.type = type;
}
#Override
public void run(){
while (true)
{
Device d = null;
try{
synchronized(q){
while(q.isEmpty())
{
q.wait(); // wait for a notify()
}
d = q.remove();
}
// do some work
// report status of work completed
}
}
Try to do something like this
ExecutorService exec = Executors.newFixedThreadPool(10);
Runnable runn = new Runnable()
{
#Override
public void run()
{
System.out.println("");
}
};
exec.execute(runn);
As mentioned best way is to use BlockingQueue. Below is the sample code:
public class PoolWorker extends Thread {
public ArrayBlockingQueue<String> q;
public String type;
public PoolWorker(ArrayBlockingQueue<String> q, String type) {
this.q = q;
this.type = type;
}
#Override
public void run() {
while(true){
String work = null;
try {
System.out.println("PoolWorker.run:waiting .............");
work = q.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("PoolWorker.run..work: " + work);
}
}
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> pool = new ArrayBlockingQueue<String>(100);
PoolWorker worker = new PoolWorker(pool, "Something");
worker.start();
addWork(pool, "work1");
addWork(pool, "work2");
addWork(pool, "work3");
addWork(pool, "work4");
addWork(pool, "work5");
//Just give enough time to run
Thread.sleep(5000);
}
private static void addWork(ArrayBlockingQueue<String> pool, String work) throws InterruptedException {
System.out.println("PoolWorker.addWork: " + work);
pool.put(work);
}
}
There is nice sample code available in Java documentation as well:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
I have a class that iterates through a list of links. For each link I want to do a treatment. So I have to create a thread for each link.
Here is the code (Main):
ThreadProcessing tp;
for(int i = 0; i < listUrl.size(); i++)
{
tp.add(string_url);
}
For the ThreadProcessing class, I have to use the Executor interface.
The point is : I have to create a pool of 30 threads. ThreadP class contains a list of non-blocking threads (it can contain more than 30 threads of course). You can add as many threads as you want and the class will be responsible to perform all these threads.
So that's what I tried to do (it does not work).The ThreadProcessing class :
public class ThreadProcessing {
List<Runnable> runnables = new ArrayList<Runnable>();
ExecutorService pool;
#PostConstruct
public void init()
{
pool = Executors.newFixedThreadPool(30);
}
public void add(String url)
{
runnables.add(createRunnable(url));
executeRunnables(pool, runnables);
}
public static void executeRunnables(final ExecutorService service, List<Runnable> runnables){
for(Runnable r : runnables){
service.execute(r);
}
service.shutdown();
}
private Runnable createRunnable(final String url){
Runnable getContentFromURL = new Runnable(){
public void run(){
//My treatment with url
}
};
return getContentFromURL;
}
}
I hope I have not been too vague in my explanation, thank you.
public void add( String url) {
Runnable job = createRunnable(url);
runnables.add( job);
pool.execute( job);
}
Also, do not shut the pool down unless you are finished submitting/adding jobs. Of course, in this example, you don't really need the runnables List.
Try something like:
public void main() {
ExecutorService es = Executors.newFixedThreadPool(30);
BlockingQueue<String> urls =
new ArrayBlockingQueue<String>(listUrl.size(), false, listUrl);
LinkedList<Future<?>> futures = new LinkedList<Future<?>>();
for(int i = 0 ; i < 30 ; ++i) {
futures.add(es.submit(new URLRunnable(urls)));
}
// Wait for all the futures to return
for(Future<?> f : futures) {
f.get();
}
}
public class URLRunnable() implements Runnable() {
private final BlockingQueue<String> urls;
URLRunnable(BlockingQueue<String> urls) { this.urls = urls; }
#Override
public void run() {
String url = null;
while((url = urls.poll()) != null) {
// do something with url
}
}
}