I found a surprising things about Thread.sleep. Thread doesn't wake up in time. Let me explain. I create an activity (no service) and run a thread like the following.
Thread.sleep(50000); // 50 seconds
System.out.println("something");
Then i keep the activity in foreground and off the display (by pressing power button). Also i was logging in a file saved in sdcard. What i found that, After almost 10 min Thread delay 7.35 minutes to print instead of 50 seconds. Is it normal?? Can i trust on Thread.sleep()?
16:47:57 ---- START
--------
-------- (all are in time)
--------
16:57:07 -- (in time)
16:57:57 -- (in time)
17:05:38 --- (late)
Can i trust on Thread.sleep()?
You can trust it to behave as specified1. But the specification says that a sleep will cause the thread to stop for at least that number of milliseconds. Under some circumstances, it could stop for longer. For example, if there is a lot of work for a higher priority thread to do, a lower priority thread may not be woken from the sleep for a long time.
1 - Actually, in theory, it might not behave as specified. But you've tendered no evidence to support that ...
You can try:
LockSupport.parkNanos(nanos)
Or other methods it provides. It's more accurate.
I found out that when you turn off the screen using power button then android go to sleep after sometimes. CPU also go to sleep when screen is off. That's whey Thread.sleep() is giving large delay. In my case my device was in sleep mode for 7.30 minute and when i turn on the screen cpu wake up and start the Thread again. By acquiring the Partial_wake_lock you can hold cpu to go to sleep even when you press the power button(not shutdown).
More details
Related
I have 1 thread group and I have defined 100 threads and 1 Iteration with a single HttpSampler. Basically I am testing a single GET API.
Now, Jmeter should start 100 threads and then they should fire request to my server which have the API. The server can respond to 100 requests concurrently. So, basically at any point in time I should have 100 concurrency.
But that is not what is happening when I checked through Blazemeter. I get a max users of 37 and total users as 100 which means max concurrency during the test was 37.
This can be possible only if Jmeter did not executed the threads parallel. So where am I wrong ?
I want all threads to execute parallel after they all are created and fire requests at once so that maximum concurrency is 100 for 1 iteration.
If you need more control and accuracy use Ultimate Thread Group JMeter plugin (instead of regular Thread Group)
Set Start Thread Count as 100, with 0 initial delay and 0 Startup Time, with positive Hold time, your thread will hold 100 max users
General example:
If your computer can't handle generating load, you may need distributed testing setup
It is not suggested to use Ramp-Up period as 0.
I think you are making confusion between concurrency (Related to virtual users) and simultaneous (Related to requests or samplers).
To hit requests simultaneously, use the Synchronizing Timer as a child of your requests. It will pause X number of threads and then released at once. And before that, to maintain the concurrency at 100 users, try to use the ramp-up time accordingly (i.e 10 seconds). So it will take 10 seconds for 100 users alive on the server and then hit the requests for 100 users simultaneously.
It doesn't matter which thread group you use but if you maintain the concurrency for more period of time (hold that concurrency), then use Ultimate Thread Group or you can use the loop count accordingly.
If you want to perform spike testing, then the regular Thread group is fine. But you have to remember that, some of your threads might already finish their work and were shut down so you won't see the expected number of the concurrent user.
Here are the example screenshots for 1 minute Test duration (100 users ramp-up time 30 sec + hold load time 20 sec + 10 sec for ramp downtime)
Ultimate Thread Group Config:
Test Results (100 requests at once):
Test Results (100 Concurrent users):
Hope it helps you to understand.
To achieve this, you can use Synchronizing_Timer. Add Synchronization Timer as a child of your GET Request.
The purpose of the SyncTimer is to block threads until X number of
threads have been blocked, and then they are all released at once. A
SyncTimer can thus create large instant loads at various points of the
test plan.
Secondly, to keep a constant load of 100 Request Per Second/Hit Per Second for a time duration, you can use Throughput Shaping Timer. Make sure, you add the Loop Count to Forever and Duration accordingly in Thread Group.
JMeter acts as follows:
The number of threads specified in the Thread Group is being kicked off during the ramp-up period
Each thread starts executing Samplers upside down (or according to the Logic Controllers)
When thread doesn't have any more Samplers to execute or loops to iterate it's being shut down
Assuming all above you may run into the situation when some threads have already finished their work and were shut down and some haven't yet been started. Check out JMeter Test Results: Why the Actual Users Number is Lower than Expected article for more comprehensive explanation if needed
Therefore the solutions are in:
Provide more "iterations" on Thread Group level to let your users loop over, this way you will have 100 concurrent users
If you need to perform some form of Spike Testing and don't want/cannot increase the number of loops just use Synchronizing Timer, this way JMeter will pause the threads until the desired amount is reached and release them at exactly the same moment
I've got some issue with executors. Is this the right way to use them?
Everything works fine for couple of hours since program execution, but then I assume threads start to behave a bit strange ...
VPNConnect thread is used to restart the vpn connection at each odd, full hour. The thread checks in the loop what time it is and when the time comes, sets flag 1 in its place on the database.
The other two independent threads do something different in the loops, while checking the flag set by the vpn thread. If the flag has been changed to 1, each thread allows the current loop to end and does not start another one. After finishing the last loop, the Rzeszowiak and NieruchomiamiGdynia thread set their flags to 0.
And now, if both of the above flags are set to 0 and the vpn flag is equal to 1, vpn is disconnected and reconnected, then the vpn thread sets its flag to 0. Threads Rzeszowiak i NieruchomosciGdynia seeing that the thread vpn has the flag 0 arouse work setting its flags on 1.
For the next 2 hours, the Rzeszowiak and NieruchomosciGdynia threads do their job while the vpn thread is set to 0. When the full, odd hour comes, the vpn thread sets its flag to 1 and the game starts again, as I described above.
So what's the problem?
For a short time after starting the program everything works as it should. For example, about 23:00 two threads finish their work, wait for the vpn restart and again arouse to work until 01:00 and then again restart vpn work until 03:00, reboot, etc ... At least it should be theory ...
Practice, however, shows that after a few (sometimes 3, sometimes 4, sometimes 6 - there is no rule) comes to the following situations:
The vpn thread does not disconnect and reconnect, although Rzeszowiak and NieruchomieniaGdynia are waiting for it (0 set on the basis).
The vpn thread disconnects and reconnects, but the Rzeszowiak and NieruchomiamiGdynia threads do not arouse.
I have a strange feeling that after some time these threads are lost somewhere or even disappear. Everything returns to order when I stop the entire program and run it again (without any manual interference in the state of the database). The situation is ok sometimes for 3 hours, sometimes 6 and sometimes even for a day ...
ConfigFile cf = new ConfigFile(args[0], args[1]);
cf.loadFile();
VPNConnect vpnConnectThread = new VPNConnect();
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(vpnConnectThread,1,60,TimeUnit.SECONDS);
if(cf.getRzeszowiak()!=null && !cf.getRzeszowiak().equals("")) {
RzeszowiakPl rzeszowiakPlThread = new RzeszowiakPl(cf.getRzeszowiak());
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(rzeszowiakPlThread,1,1,TimeUnit.SECONDS);}
if(cf.getNieruchomsciGdynia()!=null && !cf.getNieruchomsciGdynia().equals("")) {
NieruchomosciGdynia nieruchomosciGdyniaThread = new NieruchomosciGdynia(cf.getNieruchomsciGdynia());
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(nieruchomosciGdyniaThread,1,1,TimeUnit.SECONDS);}
I have my JavaFx application that reads data from API on background thread ( or for testing it is preloaded from local storage on application start ) and then it processes and sets data to model that is directly binded on properties in my view. Because processing and setting data to model changes text shown in components, it is called with Platform.runLater(). Normally when it is called it consumes around 2% of CPU, but if i run application for longer time, consumption of CPU on data processing goes higher a little bit(probably data processing is too much for GUI thread). It gets for example around +4% in 1 hour.
However what I see as strange behaviour is that when i lock my Windows and go away for few minutes and then come back, CPU usage on data processing changes from 8% to 17% for example and then stays that high. Does it mean that when Windows screen is locked then GUI thread doesn't run? It seems to me like not and then when it unlocks, GUI thread gets overwhelmed byPlatform.runLater() calls. But when it is not processing data, it consumes 0% of CPU, so i'm really confused.
Does anyone know what could cause this? Does GUI thread really stops working when windows are locked?
EDIT:
I've already found that processing received data is probably too intensive task for UI thread and I'm trying to optimize it (do most of processing on background thread and then just call setting data with Platform.runLater.
Code for background download is really simple PoF at this moment and looks like this:
Thread updateDaemon = new Thread(() -> {
try {
while (true) {
TimeUnit.SECONDS.sleep(5);
processMarketStateData(view.getTable(), data);
}
}
}
catch (InterruptedException e) {
logger.error("Background worker interrupted", e);
}
});
updateDaemon.setDaemon(true);
updateDaemon.start();
In processMarketStateData i do some processing and then set data to model on UI thread. But what i'm actually curious about is that strange CPU usage behaviour. When update thread is sleeping and i do not interact with UI then CPU usage is 0%. When processMarketStateData it takes few % of CPU and then it is again 0% till update thread ends its sleep. But for some strange reason after several processMarketStateData calls CPU usage goes up more and more. I goes up by small percentage, like 1% after 50 calls, maybe more. Even weirder is it takes way less calls to produce this strange behaviour when windows screen is locked. When it goes really insane and it takes already around 20% of CPU for call, it goes that high only on processMarketStateData call, for rest of the time it is 0%. After really long ( few hours ) test i ended up in state where application took 25% of CPU permanently and UI was inresponsive. Note that there are 2 these threads running at same time.
My actual question is not "why my ui lags when i process data", that was not hard to find, but it is "why it acts the way it does?"
I hope this edit made my question better.
EDIT2: Another strange behaviour as well is that if I leave application minimalized for a while with auto updating and open it then, it is black window for a while, but application that doesn't have auto update is ok. This really makes me think that javaFX UI thread doesn't run when application is minimalized or windows screen is locked. Sadly i could not find much about this.
probly these links may help you
Execute task in background in JavaFX
https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm
https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
This may be you are doing a cpu intensive task in UI thread . please provide some code samples.
you can use a service class to do the cpu intensive calculation and then update the ui in the plateform.runlater call.
It seems that I've found the real issue and fixed it. Unfortunately unless I would share my whole project, you would not be able to help me. Problem was that there was method called from processMarketStateData method that sets style depending on data received. Problem was that it called node.getStyleClass().add(style) without checking presence of style. So after 15 minutes size of node.getStyleClass() was around 300. After adding that check it seems that everything runs ok and it takes max 2% of CPU.
What I need in my application is do some stuff every 30 sec for 18 hours per day which I want to keep running even device going to sleep mode
for that I found two ways:
Using timer using the AlarmManager with a type of AlarmManager.ELAPSED_REALTIME_WAKEUP
Using a thread with a unfinished while-loop and sleep for thread every 30 seconds.
Now I am using timers, that works fine in all API versions but have one problem and that's battery usage.
My question is, can I use a thread instead of timers? I heard somewhere threads cannot run for very long times (5sec max), but I'm not sure.
And if I can use thread, is that take lower power than timers?
and works for all API versions?
Here is a very good description of your question
http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html
I have one method execute(data) which takes considerable time (depending on data like 10 seconds or 20 seconds), it has timeout feature which is 30 seconds default. I want to test that method. One way of doing it is to collect enough data which lasts more than 30 seconds and then see whether I get timeout exception. Other way of doing it is to use threads. What I intend to do is to run method for some milliseconds and then put thread on wait before I get timeout exception or make it last for some seconds.Can any one please suggest how can I achieve that.
You should walk through the Java Threads Tutorial (Concurrency). Any answer on Stack Overflow would need to be really long to help you here, and the Threads/Concurrency tutorials already cover this well.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
You could use
Thread.sleep( millis );
to put the thread to sleep for the required time.
Or, you could put your data processing code into a loop, so that it processes it multiple times. This would recreate the scenario of the thread actually processing data for longer than 30 seconds.
Or, you could test your code with a shorter timeout value.