I'm executing a heavy calculation on the server. The execution is launched from the front and the front is checking the status of the execution each 3 sec.
So I wrote a service like the following :
public class SomeService {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final Future<?> noop = CompletableFuture.completedFuture(null);
private final AtomicReference<Future<?>> currentExecution = new AtomicReference<>(noop);
public void execute() {
Future<?> execution = executor.submit(() -> {
// do some heavy calculation here
// ...
// ...
currentExecution.set(noop);
});
currentExecution.set(execution);
}
public boolean isRunning() {
return !currentExecution.get().isDone();
}
}
isRunning method is exposed as an api to the front.
I'm wondering if there's bugs here?
Maybe there's another elegant solution for this requirement?
A simple flag, set when the computation completes, would suffice, as long as it's volatile.
private volatile boolean done;
public void execute() {
executor.submit(() -> {
/* Do some heavy calculation here. */
done = true;
});
}
public boolean isDone() {
return done;
}
Related
This is the sequential loop:
private boolean canSpawnVehicle(SpawnPoint spawnPoint) {
// TODO: can be made much faster.
Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
for(VehicleSimView vehicle : vinToVehicles.values()) {
if (vehicle.getShape().intersects(noVehicleZone)) {
return false;
}
}
return true;
}
This is my attempt at threading through an executor service and a callable implementation class:
private boolean canSpawnVehicle(SpawnPoint spawnPoint) throws ExecutionException, InterruptedException {
// TODO: can be made much faster.
Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
ExecutorService executor = Executors.newFixedThreadPool(6);
Future<Boolean> future;
for (VehicleSimView vehicle : vinToVehicles.values()) {
future = executor.submit(new CanSpawnThread(vehicle, noVehicleZone));
if(!future.get()){
return false;
}
}
executor.shutdown();
return true;
}
This is the thread class:
public class CanSpawnThread implements Callable {
private VehicleSimView vehicle;
private Rectangle2D noVehicleZone;
public CanSpawnThread(VehicleSimView vehicle, Rectangle2D noVehicleZone){
this.vehicle = vehicle;
this.noVehicleZone = noVehicleZone;
}
public Boolean call() {
boolean can = true;
if (vehicle.getShape().intersects(noVehicleZone)){
can = false;
}
return can;
}
}
You could try with a parallelStream assuming the list has enough items to justify the threads.
I haven't tested this though.
private boolean canSpawnVehicle(SpawnPoint spawnPoint) {
Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
Optional result = vinToVehicles.values().parallelStream().filter(v -> !v.getShape().intersects(noVehicleZone)).findFirst();
return !result.isPresent();
}
Look at the loop:
for (VehicleSimView vehicle : vinToVehicles.values()) {
future = executor.submit(new CanSpawnThread(vehicle, noVehicleZone));
if(!future.get()){
return false;
}
}
You are submitting to the executor, and then waiting for the future to complete before continuing and submitting the next one. This is still just a sequential loop.
Submit all of your callables to the executor, store the Futures in a list, and then check the elements of the list to see if they have completed.
Or, better, use a CompletionService, which will give you back Futures in the order in which they complete. Once you find a Future which returns false, cancel all the others and return.
You submit a task and wait for finishing it. In this manner every thing is sequential, so you can't improve your performance. Submit all tasks and then wait to finish and check result. like this:
private boolean canSpawnVehicle(SpawnPoint spawnPoint) throws ExecutionException, InterruptedException {
// TODO: can be made much faster.
Rectangle2D noVehicleZone = spawnPoint.getNoVehicleZone();
ExecutorService executor = Executors.newFixedThreadPool(6);
List<Future<Boolean>> futures = new ArrayList();
for (VehicleSimView vehicle : vinToVehicles.values()) {
futures.add(executor.submit(new CanSpawnThread(vehicle, noVehicleZone)));
}
for(Future<Boolean> future : futures) {
if(!future.get()) {
return false;
}
}
executor.shutdown();
return true;
}
I'm developing Spring MVC web application. One of it's functionalities is file converting (uploading file -> converting -> storing on server).
Some files could be too big for converting on-the-fly so I decided to put them in shared queue after upload.
Files will be converted with priority based on upload time, i.e. FIFO.
My idea is to add task to queue in controller after upload.
There would also be service executing all tasks in queue, and if empty, then wait until new task is added. I don't need scheduling - tasks should be executing always when queue is not empty.
I've read about ExecutorService but I didn't find any example that fit to my case.
I'd appreciate any suggestions.
EDIT
Thanks for answers, I need to clarify my problem:
Basically, I know how to execute tasks, I need to manage with handling the queue of tasks. User should be able to view the queue and pause, resume or remove task from queue.
My task class:
public class ConvertTask implements Callable<String> {
private Converter converter;
private File source;
private File target;
private State state;
private User user;
public ConvertTask(Converter converter, File source, File target, User user) {
this.converter = converter;
this.source = source;
this.target = target;
this.user = user;
this.state = State.READY;
}
#Override
public String call() throws Exception {
if (this.state == State.READY) {
BaseConverterService converterService = ConverterUtils.getConverterService(this.converter);
converterService.convert(this.source, this.target);
MailSendServiceUtil.send(user.getEmail(), target.getName());
return "success";
}
return "task not ready";
}
}
I also created class responsible for managing queue/tasks followed by your suggestions:
#Component
public class MyExecutorService {
private LinkedBlockingQueue<ConvertTask> converterQueue = new LinkedBlockingQueue<>();
private ExecutorService executorService = Executors.newSingleThreadExecutor();
public void add(ConvertTask task) throws InterruptedException {
converterQueue.put(task);
}
public void execute() throws InterruptedException, ExecutionException {
while (!converterQueue.isEmpty()) {
ConvertTask task = converterQueue.peek();
Future<String> statusFuture = executorService.submit(task);
String status = statusFuture.get();
converterQueue.take();
}
}
}
My point is, how to execute tasks if queue is not empty and resume when new task is added and queue was previously empty. I think of some code that fits in add(ConvertTask task) method.
Edited after question updates
You don't need to create any queue for the tasks since the ThreadPoolExecutor implementation has its own queue. Here's the source code of Oracle's Java 8 implementation of newSingleThreadExecutor() method:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
So you just submit a new task directly and it's getting queued by the ThreadPoolExecutor
#Component
public class MyExecutorService {
private ExecutorService executorService = Executors.newSingleThreadExecutor();
public void add(ConvertTask task) throws InterruptedException {
Future<String> statusFuture = executorService.submit(task);
}
}
If you're worried about the bounds of your queue, you can create a queue instance explicitly and supply it to a ThreadPoolExecutor constructor.
private executorService = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(MAX_SIZE));
Please note that I have removed the line
String status = statusFuture.get();
because get() call is blocking. If you have this line in the same thread where you submit, your code is not asynchronous anymore. You should store the Future objects and check them asynchronously in a different thread. Or you can consider using CompletableFuture introduced in Java 8. Check out this post.
After upload you should return response immediately. The client can't wait for resource too long. However you can change it in the client settings. Anyway if you are running a background task you can do it without interacting with the client or notify the client while execution is in progress. This is an example of callable demo used by the executor service
/**
* Created by Roma on 17.02.2015.
*/
class SumTask implements Callable<Integer> {
private int num = 0;
public SumTask(int num){
this.num = num;
}
#Override
public Integer call() throws Exception {
int result = 0;
for(int i=1;i<=num;i++){
result+=i;
}
return result;
}
}
public class CallableDemo {
Integer result;
Integer num;
public Integer getNumValue() {
return 123;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Integer getResult() {
return result;
}
public void setResult(Integer result) {
this.result = result;
}
ExecutorService service = Executors.newSingleThreadExecutor();
public String execute() {
try{
Future<Integer> future = service.submit(new SumTask(num));
result = future.get();
//System.out.println(result);
service.shutdown();
}
catch(Exception e)
{
e.printStackTrace();
}
return "showlinks";
}
}
I have a class caled ItemGUI which is handling everything related with the user interface. The user, is able to add some links, which are the items, so when he inserts a link and clicks on the ADD button, it should create a new object of the class Item and start running a function called getPrice(), something like that:
Item newItem = new Item(newItemField.getText());
// should also be added to a list of items which should be in the ItemGUI class
newItem.getPrice()
This should be done after clicking the add button. Then I print the item to the table. The problem is that the method getPrice() should run every 5 seconds without blocking my GUI, so I should implement Threads.
My question is: how can I be able to implement a thread that runs that function (for each item in the list) every 5 seconds until I click on a stop button? I was thinking about using the observer-observable classes with a clock that notifies its observers every 5 seconds. Will this be the best option?
Also, will I be able to retrieve the item variables from the ItemGUI class?
Thanks!
Update
The clearest solution by MadProgrammer's suggestion is to use swing Timers, like this:
protected javax.swing.Timer refresherTimer = null;
protected void stopRefreshing() {
if (refresherTimer != null) {
refresherTimer.stop();
refresherTimer = null;
}
}
protected void startRefreshing() {
stopRefreshing();
refresherTimer = new Timer(500, e -> {
newItem.getPrice()
});
refresherTimer.start();
}
public void onStartButtonClicked() {
Item newItem = new Item(newItemField.getText());
// here newItem should be added to a list of items which should be in the ItemGUI class
startRefreshing();
}
public void onStopButtonClicked() {
stopRefreshing();
}
Original answer
It would be nice to have some utility named e.g. GuiTimer which would make your task as easy as:
protected GuiThread.Task refresherTask = null;
protected void cancelRefreshing() {
if (refresherTask != null) {
refresherTask.cancel();
refresherTask = null;
}
}
public void onStartButtonClicked() {
Item newItem = new Item(newItemField.getText());
// should also be added to a list of items which should be in the ItemGUI class
cancelRefreshing();
refresherTask = GuiThread.scheduleAtFixedRate(() -> {
newItem.getPrice()
}, 0, 5, TimeUnit.SECONDS);
}
public void onStopButtonClicked() {
cancelRefreshing();
}
The problem with regular timers is that they invoke the callback function on their own thread, not on the gui thread, so it requires the developer to ensure proper threading. Unfortunately the builtin java EventQueue does not support dispatching delayed tasks.
For this reason I like to have the following utility called GuiTimer, which will act as a pure gui-threaded timer:
public class GuiTimer {
public static final ScheduledThreadPoolExecutor executor =
new ScheduledThreadPoolExecutor(1);
public static interface Task {
public void cancel();
}
private static class CancelStateTask implements Task {
public volatile boolean canceled = false;
#Override
public void cancel() {
this.canceled = true;
}
}
public static Task schedule(final Runnable action) {
CancelStateTask task = new CancelStateTask();
EventQueue.invokeLater(() -> {
if (!task.canceled)
action.run();
});
return task;
}
public static Task schedule(final Runnable command, long delay,
TimeUnit unit) {
ScheduledFuture<?> future = executor.schedule(
() -> EventQueue.invokeLater(command), delay, unit);
return () -> future.cancel(false);
}
public static Task scheduleAtFixedRate(Runnable command,
long initialDelay, long period, TimeUnit unit) {
ScheduledFuture<?> future = executor.scheduleAtFixedRate(
() -> EventQueue.invokeLater(command), initialDelay,
period, unit);
return () -> future.cancel(false);
}
public static Task scheduleWithFixedDelay(Runnable command,
long initialDelay, long delay, TimeUnit unit) {
ScheduledFuture<?> future = executor.scheduleAtFixedRate(
() -> EventQueue.invokeLater(command), initialDelay, delay,
unit);
return () -> future.cancel(false);
}
public static void shutdown() {
executor.shutdown();
}
}
First off, I'm in no way sure how this should be done, but I think I have a suggestion for how you could make it work.
In a project I'm working on at the moment I use ExecutorService to handle my thread pool. I have to mention here, that I started working with threads in Java a little over a week ago myself, so I apologize if what I'm suggestion is too basic or wrong.
My suggestion is, that you could create a static boolean variable that you could use for controlling your loop. Code could look something like this:
public static boolean isRunning;
public static void main(String[] args) {
ExecutorService executerService = Executors.newCachedThreadPool();
executerService.execute(new Runnable() {
#Override
public void run() {
isRunning=true;
while (isRunning){
System.out.println("hello world"); //Your loop here
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Whenever you set the isRunning boolean to false the loop will stop, and the Thread will finish after a little while.
As for observer-observable classes I don't know this and I'm not sure I understand your last question.
You can use a Timer to schedule a repeating task.
Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially
Something along the lines of this code should do the trick.
Timer timer = new Timer();
TimerTask task = new TimerTask(){
public void run() {
getPrice(); //your task
}
};
timer.schedule(task, 0, 5000); //first is delay, second is repeat period
...
// on button click, simple cancel the task
task.cancel()
I am working in a method (using spring) that will manage a lot of data and information, consulting to the database and generate some files.
I am trying to avoid a timeout exception, so, I decided I should use the #Async annotation.
Not quite sure if it works as I think or not, but I also realized that I will need the method who calls Async to wait until it is finished...so, could be the same problem, couldn't it?
Is there any way I can have a sort of listener that will read the Async information that is being processed at my bean without have to wait for all the Async process to finish??
Right now is somehow like this
private Long myFIrstMethod(){
// DO A LOT OF THINGS AND CALL TO MY ASYNC METHOD
// evaluate if the Async method will have something or not... and based on it make the return
if (myOtherMethod()){
return soemvalue;
}else{
return someOtherValue
}
#Async Future<Boolean> myOtherMethod() {
//do something
new AsyncResult<Boolean>(true); //or false...
}
}
So, I was thinking, I might get a timeout exception on myFirstMethod is there any way to handle long time processing methods and avoiding this exception?
Thanks.
You could use a Timeout
http://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/TimeOut.java
Set your timeout length to the length you want to wait. In the meantime, should your method return in a timely manner, you can cancel the TimeOut.
package tjacobs.io;
public class TimeOut implements Runnable {
private long mWaitTime;
private boolean mRunning = true;
private Thread mMyThread;
private TimeOutCmd mTimeOutCmd;
public static final int DEFAULT_URL_WAIT_TIME = 30 * 1000; // 30 Seconds
public static final int NO_TIMEOUT = -1;
public static final int DEFAULT_WAIT_TIME = NO_TIMEOUT;
public static interface TimeOutCmd {
public void timeOut();
}
public TimeOut(TimeOutCmd cmd) {
this(cmd, DEFAULT_WAIT_TIME);
}
public TimeOut(TimeOutCmd cmd, int timeToWait) {
mWaitTime = timeToWait;
mTimeOutCmd = cmd;
}
public void stop() {
mRunning = false;
mTimeOutCmd.timeOut();
if (mMyThread != null) mMyThread.interrupt();
}
/**
* reset the TimeOut
*
*/
public void tick() {
if (mMyThread != null)
mMyThread.interrupt();
}
public void run () {
mMyThread = Thread.currentThread();
while (true) {
try {
Thread.sleep(mWaitTime);
stop();
}
catch (InterruptedException ex) {
if (!mRunning) {
return;
}
}
}
}
}
I want to write a reusable piece of code to allow waiting conditions while submitting tasks to an executor service. There are alot of implementaions for neat ways of blocking if too many tasks are queue, e.g. here
I need a executor that evaluates all waiting threads, every time on task is finished. For deciding if task is allowed to be submitted atm, the current state of all active tasks must be considered. I came up with the following solution, which doesn't have to scale for multiple submitters or a high grade of simultaneous executed tasks.
Question: Is the following code safe to use, or is there some flaw that I'm missing? The person implementing the aquireAccess method of the ConditionEvaluator<T> must ensure that the way the state of the threads in queried is thread safe, but the implementer needn't safeguard the iteration over the activeTasks collection. Here is the code:
public class BlockingExecutor<T extends Runnable> {
private final Executor executor;
private final ConditionEvaluator<T> evaluator;
final ReentrantLock lock = new ReentrantLock();
final Condition condition = this.lock.newCondition();
final LinkedList<T> active = new LinkedList<T>();
private final long reevaluateTime;
private final TimeUnit reevaluateTimeUnit;
public BlockingExecutor(Executor executor, ConditionEvaluator<T> evaluator) {
this.evaluator = evaluator;
this.executor = executor;
this.reevaluateTimeUnit = null;
this.reevaluateTime = 0;
}
public BlockingExecutor(Executor executor, ConditionEvaluator<T> evaluator, long reevaluateTime, TimeUnit reevaluateTimeUnit) {
this.evaluator = evaluator;
this.executor = executor;
this.reevaluateTime = reevaluateTime;
this.reevaluateTimeUnit = reevaluateTimeUnit;
}
public void submitTask(final T task) throws InterruptedException {
this.lock.lock();
try {
do{
if (this.reevaluateTimeUnit == null) {
this.condition.await(this.reevaluateTime, this.reevaluateTimeUnit);
} else {
this.condition.await();
}
}while(!this.evaluator.aquireAccess(this.active, task));
this.active.add(task);
this.executor.execute(new Runnable() {
#Override
public void run() {
try {
task.run();
} finally {
BlockingExecutor.this.lock.lock();
try{
BlockingExecutor.this.active.remove(task);
BlockingExecutor.this.condition.signalAll();
}finally{
BlockingExecutor.this.lock.unlock();
}
}
}
});
} finally {
this.lock.unlock();
}
}
}
public interface ConditionEvaluator<T extends Runnable> {
public boolean aquireAccess(Collection<T> activeList,T task);
}
Question: Can the code be improved?