There is a method which i need to update frequently for every some specific time , so i was testing java ExecutorService , but my method is not getting frequently updated , could you please tell me why ?
These are my classes
FutureTask.java
package com;
import java.lang.reflect.Method;
import java.util.concurrent.*;
public class FutureTask {
private static ExecutorService executor = Executors.newCachedThreadPool();
private static FutureTask _instance = new FutureTask();
public static FutureTask getInstance() {
return _instance;
}
private static int timoutsec = 15;
public Object submiteTask(final Object obj, final Method method,
final Object[] params) throws Exception {
return submiteTask(obj, method, params, -1);
}
public Object submiteTask(final Object obj, final Method method,
final Object[] params, int timeoutSeconds) throws Exception {
if (null != obj && method != null) {
Callable<Object> task = new Callable<Object>() {
public Object call() {
try {
method.setAccessible(true);
Object resultObj = method.invoke(obj, params);
return resultObj;
} catch (Exception e) {
}
return null;
}
};
Future<Object> future = executor.submit(task);
try {
Object result = null;
if (timeoutSeconds < 0) {
result = future.get(timoutsec, TimeUnit.SECONDS);
} else {
result = future.get(timeoutSeconds, TimeUnit.SECONDS);
}
return result;
} catch (TimeoutException e) {
} catch (Exception e) {
} finally {
future.cancel(true);
}
}
return null;
}
public static void main(String args[]) {
try {
FutureTask.getInstance().submiteTask(
new TestingFutureTaskUtil(),
TestingFutureTaskUtil.class.getDeclaredMethod(
"updateMethodCalled",
new Class<?>[] { String.class }),
new Object[] { "UBSC!OC1010" }, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
TestingFutureTaskUtil.java
package com;
public class TestingFutureTaskUtil {
public void updateMethodCalled(String symbol) {
System.out.println("updateMethodCalled" + symbol);
}
}
Thanks in advance .
You only submit one job, so updateMethodCalled is only called once.
You are using a normal ExecutorService. It doesn't allow to schedule tasks. You need to use a ScheduledExecutorService.
You need to change the following:
private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(poolSize);
and:
Future<Object> future = executor.scheduleAtFixedRate(task, timeoutSeconds, timeoutSeconds, TimeUnit.SECONDS);
Now the task will be executed every "timeoutSeconds" Seconds. Afterwards you can return the ScheduledFuture and can get the updated values from it.
Maybe it is just because of the example but I would create an callable outside and hand that to FutureTask. Than you don't need Reflection. Also the way you doing an asynchronous call is wrong because the calling thread always waits for the computation to finish. Therefore, you don't gain any benefits from the running the method in an other thread. Maybe you need to rethink the whole design of what you are doing.
Related
I've implemented a simply work queue that receives tasks from a number of different threads. I want these tasks to return a value to their source thread, but can't figure out how to do that.
I've considered using a future, but there's no way to explicitly set the future's value. I could use a property, but I don't believe those are thread safe.
Every task is an implementation of DBRequest. The actual content varies, but the result of all activities is a string.
An asynchronous thread creates a DBRequest and submits it to the queue. The queue runs the task, which produces a string. How do I get that string back to the thread that created the DBRequest, and how can I cause my creator thread to wait for the result?
public interface DBRequest {
String execute(VdtsSysDB vdtsSysDB, BoardLoad currentLoad);
}
public class DBQueue implements Runnable {
private static DBQueue dbQueue;
private LinkedBlockingQueue<DBRequest> queue = new LinkedBlockingQueue<>();
private VdtsSysDB vdtsSysDB = new VdtsSysDB();
private ReentrantLock lock = new ReentrantLock();
private static final Logger LOG = LoggerFactory.getLogger(DBQueue.class);
private boolean kill = false;
private BoardLoad currentLoad;
private ProgressController progressController;
public static DBQueue getInstance() {
if (dbQueue == null) synchronized (DBQueue.class) {
if (dbQueue == null)
dbQueue = new DBQueue();
}
return dbQueue;
}
private DBQueue() {
}
public ReentrantLock getLock() {
return lock;
}
#Override
public void run() {
LOG.info("Starting DBQueue loop. Kill {}.", kill);
while (!kill) {
DBRequest dbRequest = removeRequest();
if (dbRequest != null) {
lock.lock();
String result = dbRequest.execute(vdtsSysDB, currentLoad);
lock.unlock();
if (progressController != null) Platform.runLater(() ->
progressController.updateDisplay(currentLoad));
}
}
vdtsSysDB.getEntityManager().close();
}
public void addRequest(DBRequest dbRequest) {
try {
queue.add(dbRequest);
LOG.info("Added request.");
} catch (Exception e) {
LOG.error("Can't add element.", e);
}
}
private DBRequest removeRequest() {
DBRequest result = null;
try {
//result = queue.poll(10, TimeUnit.SECONDS);
result = queue.take();
} catch (Exception e) {
LOG.error("Exception.", e);
}
return result;
}
public void killDBQueue() {
kill = true;
LOG.info("Shutting down DBQueue.");
}
public static void start() {
Thread thread = new Thread(DBQueue.getInstance(), "DBQueue Thread");
thread.start();
LOG.info("Starting DBQueue.");
}
public BoardLoad getCurrentLoad() {
if (currentLoad == null)
currentLoad = BoardLoad.getLastOpenLoad(vdtsSysDB);
return currentLoad;
}
public void setCurrentLoad(BoardLoad proposedLoad) {
// We can only have one open load, and by definition, the current load is open. So close it.
if (this.currentLoad != null && !this.currentLoad.equals(proposedLoad)) {
currentLoad.close(vdtsSysDB);
if (proposedLoad != null) {
this.currentLoad = vdtsSysDB.getEntityManager().find(BoardLoad.class, proposedLoad.getId());
} else this.currentLoad = null;
}
}
public ProgressController getProgressController() {
return progressController;
}
public void setProgressController(ProgressController progressController) {
this.progressController = progressController;
}
}
EDIT: I'm using this queue to synchronize database access, reducing the need for locks and ensuring that requests are completed sequentially. I don't believe there is any other way to achieve this sort of asynchronous request -> synchronous request change.
But I'd love to have that belief changed.
You should add a reference to the submitting thread in your DBRequest interface and implement a setResult(String result) (or similar) method to receive the result.
You can implement a CountDownLatch waiting (or similar) on your submitting thread run() method to wait setting latch up when sending request to queue and down in setResult method.
If I'm not clear just let me know and I'll elaborate.
I'm using ExecutorService for submitting a batch of tasks. I'm doing it something like this:
ListeningExecutorService exec = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(threads));
List<ListenableFuture<Whatever>> futures = new ArrayList<>();
for (int i = 0; i < 100; i++) {
results.add(exec.submit(new MyTask(i)));
}
ListenableFuture<List<Whatever>> listListenableFuture = Futures.successfulAsList(futures);
try {
List<Whatever> responses = listListenableFuture.get(2000, TimeUnit.MILLISECONDS);
for (Whatever response : responses) {
LOG.info("Yay!");
}
} catch (TimeoutException e) {
LOG.info("Timeout Exception");
} catch (Exception e) {
// Nay!
}
The problem here is - if one of the task takes longer than 2000ms, will throw the TimeoutException and I'll get nothing in the response though some of the tasks might have finished at that very point.
So I want to retrieve the response (be it partial or complete) of the tasks that have been finished till it timeouts (2000ms). Eg:
(time relative to the START_TIME of the batch call)
Task-1: 1000ms
Task-2: 3000ms
Task-3: 1800ms
Output:
Timeout Exception
Desired Output:
Yay! <- corresponds to task-1
Yay! <- corresponds to task-3
One solution I thought of is to fetch the futures individually and set their timeout as MAX(0, TIME_OUT - TIME_NOW - START_TIME). This might work but doesn't seems like a clean solution to me.
You might use a decorate callable which handles the time out.
Suppose this is the original callable:
class OriginalCallable implements Callable<String> {
#Override
public String call() throws Exception {
return "";
}
}
You can construct a decorate callable with this original callable and the executor:
class DecorateCallable implements Callable<String> {
ExecutorService executorService;
OriginalCallable callable;
public DecorateCallable(ExecutorService executorService, OriginalCallable callable) {
this.executorService = executorService;
this.callable = callable;
}
#Override
public String call() throws Exception {
Future<String> future = executorService.submit(callable);
try {
return future.get(2000, TimeUnit.SECONDS);
} catch (TimeoutException | InterruptedException e) {
}
return null;
}
}
If you decide to use this, you need double you pool size:
Executors.newFixedThreadPool(threads * 2);
and add some condition like if(future.get() != null) before put them into the final result set.
If you use Futures.getChecked, the timeout exceptions get swallowed, and the future will return null. Check out the following code, where one of the tasks throws TimeoutException, and the corresponding future returns null.
import java.io.IOException;
import com.google.common.util.concurrent.*;
import java.time.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
public class App
{
public static void main( String[] args ) throws InterruptedException, ExecutionException
{
ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
ListenableFuture<String> future1 =
listeningExecutorService.submit(() -> {
throw new TimeoutException("Timeout exception");
});
ListenableFuture<String> future2 =
listeningExecutorService.submit(() -> "Hello World");
ListenableFuture<List<String>> combined = Futures.successfulAsList(future1, future2);
try {
String greeting = Futures.getChecked(combined, IOException.class, 2000l, TimeUnit.MILLISECONDS).stream().collect(Collectors.joining(" "));
System.out.println(greeting);
} catch (IOException e) {
System.out.println("Exception: " + e.getMessage());
} finally {
listeningExecutorService.shutdown();
}
}
}
This code always returns me 10. I think that problem with receiving list of all features. I need to parse every feature and stop execution scheduler when variable limit will equals 5. How can I do this?
static int limit = 0;
static final int testNum = 10;
static ScheduledExecutorService scheduler;
public static void main(String[] args) {
scheduler = Executors
.newScheduledThreadPool(5);
ScheduledFuture<Integer> future = scheduler.schedule(new ScheduledPrinter(), 10, TimeUnit.SECONDS);
try {
while (true) {
System.out.println(future.get());
if(future.get() != testNum){
return;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private static class ScheduledPrinter implements Callable<Integer> {
public Integer call() throws Exception {
limit++;
if(limit==5) {
scheduler.shutdown();
return limit;
}
return testNum;
}
}
Let's see What's happening here. scheduler.schedule(new ScheduledPrinter(), 10, TimeUnit.SECONDS) runs the ScheduledPrinter.call() only once. Here is the API docs.
What you want is probably a scheduleAtFixedRate. This takes a Runnable instead of a callable, so the code will look something like this:
static volatile int limit = 0; // make it volatile because of *possible* multithreaded access
// an AtomicInteger would do too
static final int testNum = 10;
static ScheduledExecutorService scheduler;
public static void main(String[] args) {
scheduler = Executors
.newScheduledThreadPool(5);
// discarding the future. No need to use it here.
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(new ScheduledPrinter(), 10L, 10L, TimeUnit.SECONDS);
}
/** Printing and counting happens here **/
private static class ScheduledPrinter implements Runnable {
#Override
public void run() {
limit++;
if(limit==5) {
scheduler.shutdown();
printNum(limit);
} else {
printNum(testNum);
}
}
private void printNum(int num) {
System.out.println(num);
}
}
Update
OP asked how to return values from Runnable.run() method? Unfortunately, it's impossible. We have to choose between periodical run and a return value because ScheduledExecutorService cannot do both.
It's still possible to get a value out of the Runnable. We must share a reference for this. Here is a rudimentary approach:
final Queue<Integer> numsPrinted = new ConcurrentLinkedQueue<>(); // a concurrent collection
ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay( // using scheduleWithFixedDelay because probably this is what you want
new ScheduledPrinter(numsPrinted), // passing the reference
10L, 10L, TimeUnit.SECONDS);
try {
future.isDone();
Object obj = future.get(80, TimeUnit.SECONDS); // blocks until 80 secs or until the task is done
System.out.println(obj);
System.out.println(Arrays.toString(numsPrinted.toArray()));
} catch (TimeoutException e) {
System.out.println(Arrays.toString(numsPrinted.toArray()));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
The ScheduledPrinter now looks like this:
private static class ScheduledPrinter implements Runnable {
private final Queue<Integer> numsPrinted;
public ScheduledPrinter(Queue<Integer> numsPrinted) {
this.numsPrinted = numsPrinted; // storing the reference
}
#Override
public void run() {
limit++;
if(limit==5) {
//scheduler.awaitTermination(timeout, unit)
scheduler.shutdown();
storeAndPrintNum(limit);
} else {
storeAndPrintNum(testNum);
}
}
private void storeAndPrintNum(int num) {
numsPrinted.add(num); // using the reference
System.out.println(num);
}
}
The method ScheduledPrinter.call() is called just one time and in the while loop you always return value that was computed once. Thus limit is never incremented and shutdown is never called. So i think you need to change logic, maybe run more threads.
I am writing an online java programming app where I take a java code as input from user and returns the output after compilation and execution through a python script.
For controlling the memory heap I have a standard solution of using -Xms and -Xmx while running the code in JVM. I have installed Sun Java 1.7.0_40.
Now the problem is that I am confused about how to restrict the code with a time limit. For example any code submitted by user in my app should not run for more than T seconds, where T is a variable.
I wrote one simple hack using Timer class but the problem is I have to use a lot of regex to inject it in the user code which I primarily want to avoid. As I am more comfortable in python and c++ than java as a programmer, I need some guidance about whether there exists some easy solution for such problem or what are the pros and cons of using the Timer class.
Any help will be much appreciated!
Thanks
I've done simple 'TimeoutThread' util using by ExecutorService.
2 classes:
package eu.wordnice.thread;
/*** Runa.java ***/
import java.util.concurrent.Callable;
public class Runa implements Callable<Object> {
private Runnable run = null;
public Runa(Runnable run) {
this.run = run;
}
public Runa(Thread run) {
this.run = run;
}
public Runa() {}
public Object call() throws Exception {
if(run != null) {
run.run();
}
return -1;
};
}
And:
package eu.wordnice.thread;
/*** TimeoutThread.java ***/
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class TimeoutThread {
public Runa run = null;
public ExecutorService executor = null;
public long timeout = 100L;
private boolean canceled = false;
private boolean runed = false;
public TimeoutThread(Runnable runit, long timeout) {
this(new Runa(runit), timeout);
}
public TimeoutThread(Runa runit, long timeout) {
this.run = runit;
if(timeout < 1L) {
timeout = 10L;
}
this.timeout = timeout;
}
public Object run() {
return this.run(false);
}
public Object run(Object defaulte) {
this.runed = true;
List<Future<Object>> list = null;
try {
this.executor = Executors.newCachedThreadPool();
list = executor.invokeAll(Arrays.asList(this.run), this.timeout, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace();
this.canceled = true;
}
executor.shutdown();
if(list == null) {
return defaulte;
}
if(list.size() != 1) {
return defaulte;
}
try {
Future<Object> f = list.get(0);
try {
return f.get();
} catch (Exception e) {
this.canceled = true;
}
} catch (Exception e) { }
return defaulte;
}
public boolean wasRunned() {
return this.runed;
}
public boolean wasCanceled() {
return this.canceled;
}
}
Example:
public static void main(String... blah) {
TimeoutThread thr = new TimeoutThread(new Runa() {
#Override
public Object call() throws Exception {
while(true) {
System.out.println("Yeeee");
Thread.sleep(300L);
}
}
}, 500L);
thr.run();
}
Print:
Yeeee
Yeeee
EDIT!
Sorry, that is Timeout Runnable. If you want Timeout Tread, just put the code / call into Thread.
public static void main(String... blah) {
final TimeoutThread thr = new TimeoutThread(new Runa() {
#Override
public Object call() throws Exception {
while(true) {
System.out.println("Yeeee");
Thread.sleep(300L);
}
}
}, 500L);
new Thread() {
#Override
public void run() {
thr.run(); //Call it
}
}.start(); //Run it
}
I would have a look at using ExecutorService in Java for this and have the class with the functionality you want to time out implement runnable - so using Java's threading capabilities to help you out.
You should be able to timeout the thread using the following code:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
But you may need to check out the documentation a bit to get it to work for your use case.
See the following post for more advice on this kind of thing.
Not sure if you're wanting to have the timeout in your python code or in Java, but hopefully this'll help a bit.
You can use ThreadPoolExecutor
sample:
int corePoolSize = 5;
int maxPoolSize = 10;
long keepAliveTime = 5000;
ExecutorService threadPoolExecutor =
new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
keepAliveTime,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()
);
threadPoolExecutor.execute(new Runnable(){
#Override
public void run() {
// execution statements
});
References
http://tutorials.jenkov.com/java-util-concurrent/threadpoolexecutor.html
I'm using a third party Java library to interact with a REST API. The REST API can sometimes take a long time to respond, eventually resulting in a java.net.ConnectException being thrown.
I'd like to shorten the timeout period but have no means of modifying the third party library.
I'd like to apply some form of timeout control around the calling of a Java method so that I can determine at what point to give up waiting.
This doesn't relate directly to network timeouts. I'd like to be able to try and perform an operation and be able to give up after a specified wait time.
The following is by no means valid Java but does conceptually demonstrate what I'd like to achieve:
try {
Entity entity = new Entity();
entity.methodThatMakesUseOfRestApi();
} catch (<it's been ages now, I don't want to wait any longer>) {
throw TimeoutException();
}
I recommend TimeLimiter from Google Guava library.
This is probably the current way how this should be done with plain Java:
public String getResult(final RESTService restService, String url) throws TimeoutException {
// should be a field, not a local variable
ExecutorService threadPool = Executors.newCachedThreadPool();
// Java 8:
Callable<String> callable = () -> restService.getResult(url);
// Java 7:
// Callable<String> callable = new Callable<String>() {
// #Override
// public String call() throws Exception {
// return restService.getResult(url);
// }
// };
Future<String> future = threadPool.submit(callable);
try {
// throws a TimeoutException after 1000 ms
return future.get(1000, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
throw new RuntimeException(e.getCause());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new TimeoutException();
}
}
There is no general timeout mechanism valid for arbitrary operations.
While... there is one... by using Thread.stop(Throwable). It works and it's thread safe, but your personal safety is in danger when the angry mob confronts you.
// realizable
try
{
setTimeout(1s); // 1
... any code // 2
cancelTimeout(); // 3
}
catch(TimeoutException te)
{
// if (3) isn't executed within 1s after (1)
// we'll get this exception
}
Now we have our nice CompletableFuture , here an application to achieve what was asked.
CompletableFuture.supplyAsync(this::foo).get(15, TimeUnit.SECONDS)
You could use a Timer and a TimerTask.
Here's a utility class I wrote, which should do the trick unless I've missed something. Unfortunately it can only return generic Objects and throw generic Exceptions. Others may have better ideas on how to achieve this.
public abstract class TimeoutOperation {
long timeOut = -1;
String name = "Timeout Operation";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getTimeOut() {
return timeOut;
}
public void setTimeOut(long timeOut) {
this.timeOut = timeOut;
}
public TimeoutOperation (String name, long timeout) {
this.timeOut = timeout;
}
private Throwable throwable;
private Object result;
private long startTime;
public Object run () throws TimeoutException, Exception {
Thread operationThread = new Thread (getName()) {
public void run () {
try {
result = doOperation();
} catch (Exception ex) {
throwable = ex;
} catch (Throwable uncaught) {
throwable = uncaught;
}
synchronized (TimeoutOperation.this) {
TimeoutOperation.this.notifyAll();
}
}
public synchronized void start() {
super.start();
}
};
operationThread.start();
startTime = System.currentTimeMillis();
synchronized (this) {
while (operationThread.isAlive() && (getTimeOut() == -1 || System.currentTimeMillis() < startTime + getTimeOut())) {
try {
wait (1000L);
} catch (InterruptedException ex) {}
}
}
if (throwable != null) {
if (throwable instanceof Exception) {
throw (Exception) throwable;
} else if (throwable instanceof Error) {
throw (Error) throwable;
}
}
if (result != null) {
return result;
}
if (System.currentTimeMillis() > startTime + getTimeOut()) {
throw new TimeoutException("Operation '"+getName()+"' timed out after "+getTimeOut()+" ms");
} else {
throw new Exception ("No result, no exception, and no timeout!");
}
}
public abstract Object doOperation () throws Exception;
public static void main (String [] args) throws Throwable {
Object o = new TimeoutOperation("Test timeout", 4900) {
public Object doOperation() throws Exception {
try {
Thread.sleep (5000L);
} catch (InterruptedException ex) {}
return "OK";
}
}.run();
System.out.println(o);
}
}
static final int NUM_TRIES =4;
int tried =0;
boolean result =false;
while (tried < NUM_TRIES && !result)
{
try {
Entity entity = new Entity();
result = entity.methodThatMakesUseOfRestApi();
}
catch (<it's been ages now, I don't want to wait any longer>) {
if ( tried == NUM_TRIES)
{
throw new TimeoutException();
}
}
tried++;
Thread.sleep(4000);
}