I would like to ask how I could implement sequential execution on methods depending on method's response.
Example:
public void processTicketing() throws TicketingException {
/** Process Steps 1-4 could throw TicketingException and does not have exact time of how long each methods will be processed.
* ? By default, is the sequence of process executions below followed from steps 1 to 4, Depending on how long each methods runs?
* If it is, then disregard this question on processes 1 to 4.
*/
processStep1();
processStep2();
processStep3();
processStep4();
for(int x=0; x < 10; x++){
//each call to this method should wait till the process is finish before calling the next one.
executeTicketCommand();
}
}
private void executeTicketCommand() throws TicketingException {
//NOTE:
//Send Request to a Web Service
//Web Service sends back a response with a status of the process
//The slower the internet, the slower the processing would be
//I want this method to finish first the processing, before being called again inside the calling loop.
if(hasError) throw new TicketingException("Error Processing Ticketing Command");
}
I am not sure whether to use synchronize or asynchronize for this scenario.
I am more concerned with the method execution of executeTicketCommand() since currently, they are invoked even if the previous executeTicketCommand() is not yet finished.
I am getting responses from the later executeTicketCommand() executions that I should wait for the current ticketing process to finish before I would start processing the next commands. This is something like lock the operation while it is still processing, after the processing... it can be run or called again.
This sample is just a representation to simplify the problem code as the real code is really complicated.
Related
I have implemented a 5-Stage CPU instruction pipeline simulator in Java using multi-threading.
Each Stage is a thread that performs mainly below 3 functions, also there is a queue (of capacity 1) in-between every two stages.
Receive from the previous stage.
Process i.e. perform its main responsibility.
Forward to the next stage.
#Override
public void run() {
while (!(latchQueue.isEmpty())) {
fetch();
process();
forward();
}
}
Simulation works fine. This is where I’m stuck, I want to be able to simulate only a specified number of clock cycles. so, the simulator should stop/pause once it has reached the specified number of cycles.
As of now, I have started all the 5 threads and let it simulate the processing of all the instructions rather than limiting it by clock cycles.
How can I accomplish this? do I need to pause thread when specified clock cycles have reached? If so how can I gracefully handle suspending/stopping the threads? Please help me in choosing the best possible approach.
Thanks in advance :)
You are already using some concurrent queue to communicate between the threads (exactly how it works isn't clear because your code example is quite incomplete).
So you can count cycles at the first stage, and use that same mechanism to communicate: shove a sentinel object, which represents "time to stop/pause this thread", onto the queue for the first stage, and when processed it pauses the processor (and still forwards it to the next stage, so all stages will progressively shut down). For example, you could extend the type of objects passed in your queue so that the hierarchy contains both real payload objects (e.g., decoded instructions, etc) or "command objects" like this stop/pause sentinel.
Another asynchronous solution would be to Thread.interrupt each thread and add an interrupt check in your processing loop - that's mostly to gracefully shut down, and not so much to support a "pause" functionality.
Will following work?
Share following class CyclesCounter between all your threads representing stages. It has tryReserve method, getting true from it means thread has got enough "clock cycles" for its' next run. Getting false means there's not enough cycles left. Class is thread-safe.
After getting false, perhaps, your thread should just stop then (i.e., by returning from run()) -- no way it can get enough nr of cycles (due to your requirements, as I understood them), until whole session is run again.
class CyclesManager {
private final AtomicInteger cycles;
CyclesManager(int initialTotalCycles) {
if (initialTotalCycles < 0)
throw new IllegalArgumentException("Negative initial cycles: " + initialTotalCycles);
cycles = new AtomicInteger(initialTotalCycles);
}
/**
* Tries to reserve given nr of cycles from available total nr of cycles. Total nr is decreased accordingly.
* Method is thread-safe: total nr of is consistent if called from several threads concurrently.
*
* #param cyclesToReserve how many cycles we want
* #return {#code true} if cycles are ours, {#code false} if not -- there's not enough left
*/
boolean tryReserve(int cyclesToReserve) {
int currentCycles = cycles.get();
if (currentCycles < cyclesToReserve)
return false;
return cycles.compareAndSet(currentCycles, currentCycles - cyclesToReserve);
}
}
I have method which is passed in real-time data constantly.
The method then evaluates the data:
void processMessage(String messageBeingPassed) {
//evaluate the message here and do something with it
//depending on the current state of the message
//if message.equals("test")
//call separate thread to save to database etc...
//etc...
}
My question is, is there any advantage to putting the entire method body inside a thread for better performance?
such as:
void processMessage(String messageBeingPassed) {
Runnable runnable = new Runnable() {
public void run() {
//evaluate the message here and do something
//depending on the current state of the message
//if message.equals("test")
//call separate thread to save to database etc...
//etc...
}
//start main body thread for this current message etc...
}
}
Thanks for any response.
It will depend on various factors. If that method is a bottleneck for your application (i.e. you get long queues of messages waiting to be processed), then it will likely improve your performance up to a certain point, and then degrade again if you use too many threads. So you should use a thread pool and have like 4 threads responsible for that, or some other amount that works best.
However, if you don't get such queues of messages, then that's hardly going to help you.
Either way, the only way to know for sure is through testing and profiling of what performs best in your application.
The advantage is that you can process multiple messages at once, and the calling method won't need to block while the message is being processed (in other words, message processing will be asynchronous instead of synchronous). The disadvantage is that you open yourself up to data races / deadlocks / etc if you're not careful about designing your methods - generally, if your runnable will ONLY be operating on the messageBeingPassed object (and not e.g. on any static fields), then you should be fine. In addition, threads carry some overhead with them, which you can reduce by using an ExecutorService instead of constructing your own thread objects.
It's depend on the rate of data and the time taken by the "processMessage". If the next data arrives before the "processMessage" method finishes its execution of the previous data, it is a good idea to use a thread inside the "processMessage" method
Right now, I have a piece of code that contacts another server asking if an item is in a list, and returns a boolean value based on that returned value.
The code goes like so:
public boolean checkIfOnline(int accountId) {
//First loop is incase if someone is already checking. Second is for the checking that this account is doing.
while (isCheckingIfOnline) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
}
isCheckingIfOnline = true;
sendCheckIfOnline(accountId);
while (isCheckingIfOnline) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
}
}
return onlineResponse;
}
The onlineResponse and isCheckingIfOnline are changed within a method that handles what the other server returns, and this is the method I've thrown together to have the system wait for the other server to respond. Obviously, this is very flawed, as when this method gets called often, it'll slow down the system since it only allows for one query at a time, when it should allow for multiple queries to be executed simultaneously.
What other method could I use that accomplishes what the above code does, but allows for more than one query to run at once?
Edit: To clarify even more, checkIfOnline takes an account ID, and asks another server is that account ID is on a list, which that other server responds to the current server if the account ID is or is not on the list.
Sounds like you would want to make use of the ExecutorService in Java 6+.
The ExecutorService requires you to submit to it a class that implements Callable. When you submit a Callable to a ES, you receive back a Future that you can use to do a number of things, including cancelling the process or getting a result from a completed process.
It's a little hard for me to understand exactly what you are trying to achieve with your code and why you're threading that particular part. That being said, if you want to achieve concurrency there, you'd have to:
submit a Callable to the ES that does the online checks & query;
provide a way for the Callable to notify the your application that it has finished it's execution.
It will not be sufficient to simply submit the task and call Future.get() on it because whatever thread makes that call will be suspended until the task is completed.
You'd need to either allow the Callable to invoke a callback, or thread the class that performs the submission of the task and allow it to sit and wait for the future.get() method to return a result.
Good luck :)
I'm trying to create a method that executes a given task in a maximum amount of time. If it fails to finish in that time, it should be retried a number of times before giving up. It should also wait a number of seconds between each try. Here's what I've come up with and I'd like some critiques on my approach. Is their a simpler way to do this using the ScheduledExecutorService or is my way of doing this suffice?
public static <T> T execute(Callable<T> task, int tries, int waitTimeSeconds, int timeout)
throws InterruptedException, TimeoutException, Exception {
Exception lastThrown = null;
for (int i = 0; i < tries; i++) {
try {
final Future<T> future = new FutureTask<T>(task);
return future.get(timeout, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
lastThrown = ex;
} catch (ExecutionException ex) {
lastThrown = (Exception) ex.getCause();
}
Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSeconds));
}
if (lastThrown == null) {
lastThrown = new TimeoutException("Reached max tries without being caused by some exception. " + task.getClass());
}
throw lastThrown;
}
I think, but it's my opinion, that if you are scheduling network related tasks, you should not retry but eventually run them in parallel. I describe this other approach later.
Regarding your code, you should pass the task to an executor, or the FutureTask to a thread. It will not spawn a thread or execute by itself. If you have an executor (see ExecutorService), you don't even need a FutureTask, you can simply schedule it and obtain a callable.
So, given that you have an ExecutorService, you can call :
Future<T> future = yourExecutor.submit(task);
Future.get(timeout) will wait for that timeout and eventually return with TimeoutException even if the task has never started at all, for example if the Executor is already busy doing other work and cannot find a free thread. So, you could end up trying 5 times and waiting for seconds without ever giving the task a chance to run. This may or may not be what you expect, but usually it is not. Maybe you should wait for it to start before giving it a timeout.
Also, you should explicitly cancel the Future even if it throws TimeoutException, otherwise it may keep running, since nor documentation nor code says it will stop when a get with timeout fails.
Even if you cancel it, unless the Callable has been "properly written", it could keep running for some time. Nothing you can do it about it in this part of code, just keep in mind that no thread can "really stop" what another thread is doing in Java, and for good reasons.
However I suppose your tasks will mostly be network related, so it should react correctly to a thread interruption.
I usually use a different strategy is situations like this:
I would write public static T execute(Callable task, int maxTries, int timeout), so the task, max number of tries (potentially 1), max total timeout ("I want an answer in max 10 seconds, no matter how many times you try, 10 seconds or nothing")
I start spawning the task, giving it to an executor, and then call future.get(timeout/tries)
If I receive a result, return it. If I receive an exception, will try again (see later)
If however i get a timeout, I DON'T cancel the future, instead I save it in a list.
I check if too much time has passed, or too many retries. In that case I cancel all the futures in the list and throw exception, return null, whatever
Otherwise, I cycle, schedule the task again (in parallel with the first one).
See point 2
If I have not received a result, I check the future(s) in the list, maybe one of the previous spawned task managed to do it.
Assuming your tasks can be executed more than once (as I suppose they are, otherwise no way to retry), for network stuff I found this solution to work better.
Suppose your network is actually very busy, you ask for a network connection, giving 20 retries 2 seconds each. Since your network is busy, none of the 20 retries manages to get the connection in 2 seconds. However, a single execution lasting 40 seconds may manage to connect and receive data. It's like a person pressing f5 compulsively on a page when the net is slow, it will not do any good, since every time the browser has to start from the beginning.
Instead, I keep the various futures running, the first one that manages to get the data will return a result and the others will be stopped. If the first one hangs, the second one will work, or the third one maybe.
Comparing with a browser, is like opening another tab and retrying to load the page there without closing the first one. If the net is slow, the second one will take some time, but not stopping the first one, which will eventually load properly. If instead the first tab was hung, the second one will load rapidly. Whichever loads first, we can close the other tab.
The thread on which your execute is called will block for so much time. Not sure if this is correct for you. Basically , for these types of tasks , ScheduledExecutorService is best.You can schedule a task and specify the timings. Take a look at ScheduledThreadPoolExecutor
In the playframework's documentation here has been written:
public static void loopWithoutBlocking() {
for(int i=0; i<=10; i++) {
Logger.info(i);
await("1s");
}
renderText("Loop finished");
}
I do not really understand how exactly it works:
for example when we are calling the method in first request i = 1, then .. unlocking and waiting.. and new request goes to the method and then it starts form i=0 again? and when first request awake it will have i=1 or 0 or 2?
It does not use any stateful mechanism here? like storing i.. between request for example?
The way this work in Play 1.1, was to use the suspend function, which was replaced in Play 1.2 with await(). In 1.1, the suspend function did not start the process off at the same point, but simply recalled the method, with the same inputs after the process had "suspended" for the specified amount of time.
The reason for this, is to ensure that the Thread that is "sleeping" is not blocking other requests from being processed (try in Dev mode, where only 1 thread is running, and await for 10seconds, you can still send a second request, and it is processed). So, in Play1.1, you would have had to maintain state.
The difference in Play 1.2, and using await, is that the restarting of the method is done behind the scenes, and it restarts the method at the point it left off, so the state of the variables should also be preserved.
In your example (taken from the docs), it should simply loop from zero to 9, and at each point, wait for 1 second. If you are not experiencing this, then I believe it is a bug.