I have async method where I use DeferredResult as return type. I want write junit test for that method where I call this method in loop, e.g 100 times, and I need measure execution time for every call of that method.
Here is method sample:
#Transactional(readOnly = true)
#Override
public DeferredResult foo() {
DeferredResult dr = new DeferredResult(5000L, "timeout");
dr.onCompletion(() -> {
// do some stuff
});
deferredResults.add(dr);
return dr;
}
created deferredResult I add into collection, and I iterate that collection in another method where I set some result, and then is dr returned.
Can you show my how should looks like test where I will be able measure execution time of multiple calls of that method?
#Test
public void executionTimeTest() {
for (int i = 0; i < 100; i++) {
asyncService.foo();
}
// here I need get execution time for each call
}
Thanks.
I think the best way to solve this question is adding additional data in DeferredResult class as it is recommended by spring docs. Precisely, the following sentence in spring docs points out this possibility.
Subclasses can extend this class to easily associate additional data
or behavior with the DeferredResult. For example, one might want to
associate the user used to create the DeferredResult by extending the
class and adding an additional property for the user. In this way, the
user could easily be accessed later without the need to use a data
structure to do the mapping.
Given this possibility, you can extend the DeferredResult and add a start and end time:
public class MyDeferredResult extends DeferredResult {
long startTime;
long endTime;
public MyDeferredResult(Long timeout, Object timeoutResult) {
super(timeout, timeoutResult);
this.startTime = System.currentTimeMillis();
}
#Override
public boolean setResult(Object result) {
boolean r = super.setResult(result);
this.endTime = System.currentTimeMillis();
return r;
}
public long totalTime() {
return (endTime - startTime)/1000;
}
}
Then, your Async Service can be similar to this one:
public MyDeferredResult foo() {
MyDeferredResult dr = new MyDeferredResult(5000L, "timeout");
new Thread(() -> {
Random r = new Random();
System.out.println("async task started");
try {
Thread.sleep(r.nextInt(4) * 1000 );
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("async task finished");
dr.setResult("test async result");
}).start();
deferredResults.add(dr);
return dr;
}
boolean hasResults() {
boolean result = true;
for(MyDeferredResult dr: deferredResults) {
result = result && dr.hasResult();
}
return result;
}
Finally, in your test, you can retrieve the total time of each execution:
#Test
public void executionTimeTest() {
Service service = new Service();
for (int i = 0; i < 10; i++) {
service.foo();
}
while (!service.hasResults()) {
System.out.println("No result yet");
}
for(MyDeferredResult dr: service.deferredResults) {
System.out.println(dr.totalTime());
}
}
Related
I need to provide code that using ExecutorService, Callable and Future will be doing some calculations and printing the partial results until defined condition is reached. First thing that comes to my mind is using while loop. Unfortunately as I understand ExecutorService.get() waits until the task is done, so I cannot do something like (pseudo code):
public Object call() throws Exception {
try {
while(!condition) {
//perform calc
return partialCalculationResult;
}
}
catch(InterruptedException e){
}
}
Could anyone guide me what's the proper direction I should go for?
This here:
while(!condition) {
//perform calc
return partialCalculationResult;
}
indicates a "hole" in your logic. This should probably go like this instead:
while(!condition) {
// perform computation
push intermediate results somewhere
}
return finalResult;
In other words: you are talking about two different elements here. For those "progress" updates you will need some kind of shared data structure; for example a Queue.
You see, in difference to other languages, there is no built-in "generator" concept that would allow you to yield values from a loop; like you can do in python or scala for example.
The dirty option is putting a System.out.println within the while loop.
The cleaner option would be a publish/subscriber pattern, like:
interface Subscriber {
void onPartialResult(double partialResult);
}
class SystemOutSubscriber implements Subscriber{
#Override
void onPartialResult(double partialResult) {
System.out.println(partialResult);
}
}
class YourCalculatorClass {
List<Subscriber> subscribers = ...
public Object call() throws Exception {
while(!condition) {
//perform calc
for(Subscriber s : subscribers) {
s.onPartialResult(partialCalculationResult);
}
}
}
}
You can use Thread.interrupt to stop the thread inside while loop and add remaining result in list
while(!condition){ list.add(addResultHere)
Thread.interrupt(); }
Below is a small example of using an ExecutorService
to push callable tasks. I push them inside a while loop now for the ease of the example, but they can come from anywhere. The callable itself uses the most silly easy example of course where it takes in a number. If the number is below 5, all is good, and we return a text. If not, we return nothing. When the future is evaluated and the result is empty, we shut down the ExecutorService and call it a day. So, this is an example of using an ExecutorService, Callable, and Future to do something at least similar to what I could discern from your explanation.
public ExecutorServiceTest() {
ExecutorService service = Executors.newCachedThreadPool();
int num = 0;
while (true) {
Future<Optional<String>> future = service.submit(new MyCallable(num++));
try {
Optional<String> result = future.get();
if (!result.isPresent()) {
service.shutdown();
break;
}
System.out.println(result.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
service.shutdown();
}
}
}
private static class MyCallable implements Callable<Optional<String>> {
private final int num;
MyCallable(int num) {
this.num = num;
}
#Override
public Optional<String> call() throws Exception {
if (num < 5)
return Optional.of("My number is " + num);
return Optional.empty();
}
}
public static void main(String[] args) {
new ExecutorServiceTest();
}
I have a list of 30 servers and I have to make a REST call to each server to get their status. Currently I iterating through list of server and sequentially calling each REST call against each server. So totally it takes around 30 seconds in total to get the response from each server before returning the result to JSP VIEW.
How can we improve this?
One option you could consider is the Java8 streams like:
public void check() {
List<String> endPoints = Arrays.asList("http://www.google.com", "http://www.stackoverflow.com", "inexistent");
{
// this will execute the requests in parallel
List<Boolean> collected = performCheckOverStream(endPoints.parallelStream());
System.out.println(collected);
}
{
// this will execute the requests in serial
List<Boolean> collected = performCheckOverStream(endPoints.stream());
System.out.println(collected);
}
}
private List<Boolean> performCheckOverStream(Stream<String> stream) {
List<Boolean> collected = stream.map(new Function<String, Boolean>() {
#Override
public Boolean apply(String t) {
// do what you need here
}
}).collect(Collectors.toList());
return collected;
}
Using Spring you could either use a #Async annotated method or even use the AsyncRestTemplate, in both cases you will receive a Future<?>. A nice introduction to #Async can be found here and to the AsyncRestTemplate here.
You can do it via ThreaPool like this , with Thread count as your API call count.
public void REST_Thread_executor(int Thread_count, ArrayList URLS) {
ExecutorService executor = Executors.newFixedThreadPool(Thread_count);
for (int i = 0; i < Thread_count; i++) {
String URL = URLS.get(i).toString();
Runnable worker = new MyRunnable(URL);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
}
public String restAPICALL(URL) {
GET or POST or PUT or DELETE
}
public static class MyRunnable implements Runnable {
private final String URL;
RESTThreadExecutor restThreadExecutor = new RESTThreadExecutor();
MyRunnable(String URL) {
this.URL = URL;
}
#Override
public void run() {
restThreadExecutor.restAPICALL(URL);
}
}
You can use the CompletableFuture Interface from java 9. Or the enable on your app the #EnableAsync and on your method use the #Async that will return to you an interface Future.
The both are asynchronous stream.
I have a piece of code that needs to make 15 requests in parallel then wait for all the requests to complete before proceeding.
Each request takes somewhere between 500-2500 ms. Is there a way in Java to get the time it takes for each future to complete the request?
I don't know of any built in methods in the Future api itself. However, if you use ListenableFutures, you can start a timer when you make the future and and stop the timer in the onSuccess or onFailure callback. Concretely, this could look something like:
public void timeRequests(MyRequests[] requestsToMake) {
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(requestsToMake.length));
long startTimeNanos = System.nanoTime();
long[] endTimes= new long[requestsToMake.length]
for(int i =0; i < requestsToMake.length; i++){
MyRequest req = requestsToMake[i];
ListenableFuture<MyData> rFuture = service.submit(new Callable<MyRequest>() {
public MyData call() {
return req.makeRequest();
}
});
Futures.addCallback(rFuture, new FutureCallback<MyData>() {
public void onSuccess(MyData data) {
endTimes[i]=System.nanoTime();
//whatever else you do
}
public void onFailure(Throwable thrown) {
endTimes[i]=System.nanoTime();
//whatever else you do
}
});
}
i'm triyng to experiment the multithread programming (new for me) and i have some questions.
I'm using a ThreadPoolTaskExecutorwith a TestTask which implements Runnable and a run method wich sleeps for X seconds. Everyting went smoothly and all my TestTask were executed in a different thread. Ok.
Now the tricky part is that i want to know the result of an operation made in the thread. So i read some stuff on Google/stack/etc and i tried to use Future. And it's not working well anymore :/
I use the get method to get (oh really ?) the result of the call method and that part is working but the TestTask are executed one after another (and not at the same time like before). So i'm guessing i didn't understand properly something but i don't know what... and that's why i need your help !
The class wich launch test :
public void test(String test) {
int max = 5;
for (int i = 0; i < max; i++) {
TestThreadService.launch(i);
}
System.out.println("END");
}
The TestThreadService class :
public class TestThreadService {
private ThreadPoolTaskExecutor taskExecutor;
public void launch(int i) {
System.out.println("ThreadNumber : "+i);
taskExecutor.setWaitForTasksToCompleteOnShutdown(false);
TestTask testTask = new TestTask(i);
FutureTask<Integer> futureOne = new FutureTask<Integer>(testTask);
taskExecutor.submit(futureOne);
try {
Integer result = futureOne.get();
System.out.println("LAUNCH result : "+i+" - "+result);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setTaskExecutor(ThreadPoolTaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
}
And the TestTask Class :
public class TestTask implements Callable<Integer> {
public Integer threadNumber;
private Integer valeur;
public TestTask(int i) {
this.threadNumber = i;
}
public void setThreadNumber(Integer threadNumber) {
this.threadNumber = threadNumber;
}
#Override
public Integer call() throws Exception {
System.out.println("Thread start " + threadNumber);
// generate sleeping time
Random r = new Random();
valeur = 5000 + r.nextInt(15000 - 5000);
System.out.println("Thread pause " + threadNumber + " " + valeur);
try {
Thread.sleep(valeur);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread stop" + threadNumber);
return this.valeur;
}
}
I'm not bad in Java but this is the first time i'm trying to use different thread so i'ts kind a new for me.
What am i doing wrong ?
Thanks !
In your test method,
TestThreadService.launch(1);
should probably be
TestThreadService.launch(i);
Main thing though is the
Integer result = futureOne.get();
call in the launch method. Calling get() on a FutureTask is a blocking operation, meaning it will not return until the task is completed. That is why you are seeing a serial behavior. The use-case you are emulating (farming a bunch of activities and waiting for them to complete) is not one that the ThreadPoolTaskExecutor is ideally suited for. It does not have the "join" feature that raw threads have. That beeing said, what you want to do is something like
public Future<Integer> launch(int i) {
System.out.println("ThreadNumber : "+i);
taskExecutor.setWaitForTasksToCompleteOnShutdown(false);
TestTask testTask = new TestTask(i);
FutureTask<Integer> futureOne = new FutureTask<Integer>(testTask);
return taskExecutor.submit(futureOne);
}
And in your test method
public void test(String test) {
List<Future<Integer>> tasks = new ArrayList<Future<Integer>>();
int max = 5;
for (int i = 0; i < max; i++) {
tasks.add(TestThreadService.launch(i));
}
for (Future<Integer> task : tasks) {
System.out.println("LAUNCH result : " + task.get());
}
System.out.println("END");
}
also you can move setWaitForTasksToCompleteOnShutdown(false) into another method, for to dont be called each time you launch a thread, which is, as i see, (not very much threads), but in another scenario, with more tasks: an unnecessary and expensive job.
You can also create a public method on service, called: configure(); or, pre-launch(); before you start creating threads.
gluck!
I have several classes that implement some interface. The interface has a contract, that some methods should be synchronized, and some should not, and I want to verify that contract through unit tests for all the implementations. The methods should use the synchronized keyword or be locked on this - very similar to the synchronizedCollection() wrapper. That means I should be able to observe it externally.
To continue the example of Collections.synchronizedCollection() if I have one thread calling iterator(), I should still be able to get into methods like add() with another thread because iterator() should not do any locking. On the other hand, I should be able to synchronize on the collection externally and see that another thread blocks on add().
Is there a good way to test that a method is synchronized in a JUnit test? I want to avoid long sleep statements.
If you just want to check if a method has the synchronized modifier, aside from the obvious (looking at the source code/Javadoc), you can also use reflection.
Modifier.isSynchronized(method.getModifiers())
The more general question of testing if a method guarantees proper synchronization in all concurrency scenarios is likely to be an undecidable problem.
These are all horrible ideas, but you could do this...
1
// Substitute this LOCK with your monitor (could be you object you are
// testing etc.)
final Object LOCK = new Object();
Thread locker = new Thread() {
#Override
public void run() {
synchronized (LOCK) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
return;
}
}
}
};
locker.start();
Thread attempt = new Thread() {
#Override
public void run() {
// Do your test.
}
};
attempt.start();
try {
long longEnough = 3000 * 1000;// It's in nano seconds
long before = System.nanoTime();
attempt.join(longEnough);
long after = System.nanoTime();
if (after - before < longEnough) {
throw new AssertionError("FAIL");
} else {
System.out.println("PASS");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
locker.interrupt();
2
If you know that methods on the arguments are always invoked in any implementation, you can pass a mock object that disguises as the argument and calls holdsLock().
So like:
class Mock implements Argument {
private final Object LOCK;
private final Argument real;
public Mock(Object obj, Argument real){
this.LOCK=obj;
this.real = real;
}
#Overrides
public void something(){
System.out.println("held:"+Thread.holdsLock(LOCK));
this.real.something();
}
Then wait for the class to invoke something() on Argument.
A big thank you to Zwei steinen for writing up the approach I used. There are a few problems in the example code that I worked through, so I thought it would be worth posting my findings here.
The call to join() expects a number of milliseconds, not nanoseconds.
The two threads must be coordinated, otherwise the attempt thread can start and finish all before the locker thread grabs the lock.
The attempt thread should not be started until after we record the start time. Otherwise that thread gets enough of a head start that the recorded time can be slightly less than the timeout, causing spurious failures.
Here is the synchronization test code as a Scala trait:
trait SynchronizedTestTrait
{
val classUnderTest: AnyRef
class Gate
{
val latch = new java.util.concurrent.CountDownLatch(1)
def open()
{
this.latch.countDown
}
def await()
{
this.latch.await
}
}
def nanoTime(code: => Unit) =
{
val before = System.nanoTime
code
val after = System.nanoTime
after - before
}
def assertSynchronized(code: => Unit)
{
this.assertThreadSafety(threadSafe = true, millisTimeout = 10L)(code)
}
def assertNotSynchronized(code: => Unit)
{
this.assertThreadSafety(threadSafe = false, millisTimeout = 60L * 1000L)(code)
}
def assertThreadSafety(threadSafe: Boolean, millisTimeout: Long)(code: => Unit)
{
def spawn(code: => Unit) =
{
val result = new Thread
{
override def run = code
}
result.start()
result
}
val gate = new Gate
val lockHolderThread = spawn
{
this.classUnderTest.synchronized
{
// Don't let the other thread start until we've got the lock
gate.open()
// Hold the lock until interruption
try
{
Thread.sleep(java.lang.Long.MAX_VALUE)
}
catch
{
case ignore: InterruptedException => return;
}
}
}
val measuredNanoTime = nanoTime
{
// Don't start until the other thread is synchronized on classUnderTest
gate.await()
spawn(code).join(millisTimeout, 0)
}
val nanoTimeout = millisTimeout * 1000L * 1000L
Assert.assertEquals(
"Measured " + measuredNanoTime + " ns but timeout was " + nanoTimeout + " ns.",
threadSafe,
measuredNanoTime > nanoTimeout)
lockHolderThread.interrupt
lockHolderThread.join
}
}
Now let's say we want to test a simple class:
class MySynchronized
{
def synch = this.synchronized{}
def unsynch = {}
}
The test looks this:
class MySynchronizedTest extends SynchronizedTestTrait
{
val classUnderTest = new MySynchronized
#Test
def synch_is_synchronized
{
this.assertSynchronized
{
this.classUnderTest.synch
}
}
#Test
def unsynch_not_synchronized
{
this.assertNotSynchronized
{
this.classUnderTest.unsynch
}
}
}
Using reflection, get the method's Method object, and invoke toString() on it. The "synchronized" keyword should appear in toString()'s output.