I'm trying to make some calculations using Multi threading. At maximum I will have to make 100 different calculations. Even when I tried to balance the start of threads from 10 each time, I am having messages of threads suspending on Log Cat. I think this is killing the performance. When I just launch 10 threads the performance is good.
//launch thread for each accuracy values
executor = Executors.newFixedThreadPool(100/accuracyInterval);
int countThreads = 0;
for(Integer acc: listAccuracies){
Runnable worker = new MyRunnable(acc);
if(accuracyInterval != 10) {
if (countThreads == 10) {
while (threadsDoneCounter < 10) {
//Log.d("THREADS ","WAITING");
}
countThreads = 0;
}
}
executor.execute(worker);
countThreads ++;
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
Now the code for MyRunnable
public class MyRunnable implements Runnable {
private final int accuracy;
MyRunnable(int accuracy) {
this.accuracy = accuracy;
}
#Override
public void run() {
Log.d("THREAD " , Integer.toString(accuracy) + " START");
try {
calculatePrediction(accuracy);
} catch (Exception e) {
}
threadsDoneCounter++;
Log.d("THREAD " , Integer.toString(accuracy) + " END");
}
}
What can do make it have a better performance when i have to launch for example 100 threads? what i am doing wrong?
Thanks for the attention,
Regards
Related
To prevent ANR on Android you could implement a Watchdog Timer which would require to have another Thread running and waiting for heartbeats. If you expect your App to have a refresh rate of 30FPS, guard for a refresh rate of lower than 15FPS. This covers also the case when you would have potentially an ANR in the future.
If you know the places where the UI might get stuck for a long time, you can build the watchdog to guard against this (skip current frame for example). If it is to long why are you doing it on the UI? If the action you are performing refers to redrawing the screen you can not do it somewhere else.
Here I made a simple example of a watchdog.
public class MainActivity extends AppCompatActivity {
int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread watchdogThread = new Thread(new Runnable() {
long lastT = System.currentTimeMillis();
long lastCount = 0;
long missed = 0;
#Override
public void run() {
while(true){
if (System.currentTimeMillis()-lastT>1500){
if (count == lastCount){
missed++;
}
lastCount = count;
if (missed > 3){
Log.e("test", "Error");
}
lastT = System.currentTimeMillis();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
watchdogThread.start();
startCycleUI();
}
private void startCycleUI() {
//Runs on UI Thread
long lastT = System.currentTimeMillis();
while(true){
if (System.currentTimeMillis()-lastT>1000){
if (count < 10) {
count++;
}
lastT = System.currentTimeMillis();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
When you do not know where to look, is there a way you could build a watchdog timer that simply restarts the application? How can this watchdog timer live beyond the application context?
You can use the example from "Java Source Code Warehouse" project
You have options to:
Monitor the memory in a particular process
Kill the process if they don't return
Check memory usage in the system, scheduling kills/reboots as needed.
Can I use a thread for increment a counter and shows it in a frame of Android activity.
Public class MainActivity extendsActivity {
TextView counter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
counter = (TextView) findViewById(R.id.TV_counter);
Thread t = new Thread() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
counter.setText("" + i);
System.out.println("Value of i= " + i);
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
};
t.start();
}
}
I wrote this code, but it run properly in console, but the text view displays i=4 in the terminal, I modified the time to sleep(3000) and the problem persists.
First you don't ever want to put sleep in UI Thread that can lead to unresponsive user interface and that is never good. You should use it just to update your graphics. Try replacing your code with this
Thread t = new Thread() {
public void run() {
for (int i = 0; i < 5; i++) {
try {
final int a = i;
runOnUiThread(new Runnable() {
public void run() {
counter.setText("" + a);
}
});
System.out.println("Value of i= " + i);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
You are going to notice that sleep and for loop is outside UIThread and in your first thread, so basically all of your math is done outside and you just display the results.
This is just a correction of your code and suggestion for further thinking
EDIT: And for you to better understand why your code is not working, you set some value on your TextView, and immediately after you set UIThread to sleep, UIThread blocks instead of giving it time to finish updating graphics, after he finish sleep you set new value, and he never got to update previous one so in the end you see just the last one.
Hope this helps and enjoy your work.
you can use a CountDownTimer, and update your UI in the onTick() method ( this method is executed on the UI Thread):
int i=0;
CountDownTimer timer = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
// this method will be executed every second ( 1000 ms : the second parameter in the CountDownTimer constructor)
i++;
txt.setText(i);
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
};
timer.start();
I'm testing Think in Java's Multi thread like this in Android:
private void testDeamon(){
Thread d = new Daemon();
System.out.println(
"d.isDaemon() = " + d.isDaemon());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class Daemon extends Thread {
private static final int SIZE = 10;
private static final String TAG = null;
private int i = 9000;
private Thread[] t = new Thread[SIZE];
public Daemon() {
setDaemon(true);
start();
}
public void run() {
for(int i = 0; i < SIZE; i++)
t[i] = new DaemonSpawn(i);
for(int i = 0; i < SIZE; i++)
System.out.println(
"t[" + i + "].isDaemon() = "
+ t[i].isDaemon());
while(true) {
Log.d(TAG, "Deamon running..."+ i--);
if (i==0)
break;
yield();
}
}
class DaemonSpawn extends Thread {
public DaemonSpawn(int i) {
System.out.println(
"DaemonSpawn " + i + " started");
start();
}
public void run() {
while(true)
yield();
}
}
}
Why the spawn daemon's outcome is false, so the spawn of a daemon is not daemon here
Why the Daemon thead keep running after the Android application exit? According to the TIJ, the JVM exit after all non-deamon thread killed and the deamon thread exit too. So the JVM is not shutdown after application destroyed? Thanks.
I can't answer the first question. They should be daemons too (http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ315_005.htm)
For Android purposes, daemon threads or non-daemon threads are moot. Your app's process never exits: It either remains in the background or it gets killed at some point.
Your second question:
What do you mean by "... Android application exit..."? Apps don't 'exit', they just go into the background and, if the OS deems it necessary, they may get killed.
In other words, when your app goes into the background, it doesn't exit. It keeps running in the background (until it gets killed at some point).
I am trying to make view of random text 3 times with time pausing between.
I just can't! It all run all together. I admit I don't know thread subject at all, I just need simple solution.
public void loading3() {
Random randomDouble = new Random();
temp = (double) randomDouble.nextInt(100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
result.setText(temp + "%");
}
This is the code. I want to use it let's say 3-4 times in a row. How can i do it? I try inside loop or writing same methods in a row but it won't work because it doesn't wait for the first method to end before start the new one.
You should not sleep on the main thread. This can easily be done with a Handler or Timer. Here is an example with a Handler:
private int mCount = 0;
private Handler mHandler = new Handler();
private Runnable mUpdater = new Runnable() {
public void run() {
Random randomDouble = new Random();
temp = (double) randomDouble.nextInt(100);
result.setText(temp + "%");
mCount++;
if (mCount < 3)
mHandler.postDelayed(mUpdater, 1000);
}
}
public void loading3() {
mHandler.postDelayed(mUpdater, 1000);
}
Can wait/notify be used within one thread?
I'm mean I have a listener and in the moment when that listener gets called I wanna enable a thread to do his work.How could I do that?
UPDATE:My data is written in a database...and is written each time the listener is called.Now the thread that I've created reads that data and sends it somewhere....
Next...I get some other data and do the same thing....The other thread needs to know what was the last data he read it so he can start reading from where he left....
Take a look in here:
using wait and notify within one thread
This is how my problem looks like.Thx
I have the following:
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
in MyThread....so when I do
MyThread t = new MyThread(syncToken);
t.start();
I put my thread on waiting...yes?
And when I do this:
syncToken.notify();
I get my thread back on track....but the execution of the next line is the one after wait()?
I mean this: System.out.println("MyThread: " + s); ????
When u notify a thred does he continues his execution with the line after wait()???Thx
The following is a simple example of concurrency between two different threads. In the example the main thread start a MyThread thread and every 3 seconds it sets a data to the MyThread instance and then MyThread prints it. The idea is to have a synchronized object that you wait on it and notify in the end of the usage to other threads that they can use it:
Test.java:
package stack;
public class Test {
public static void main (String args[])
{
Object syncToken = new Object();
MyThread t = new MyThread(syncToken);
t.start();
for (int i = 0; i < 10; i++)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(syncToken)
{
t.setText("Iteration " + i);
syncToken.notify();
}
}
}
}
MyThread.java:
package stack;
public class MyThread extends Thread{
String s;
Object syncToken;
public MyThread(Object syncToken)
{
this.s = "";
this.syncToken = syncToken;
}
public void run()
{
while(true) // you will need to set some condition if you want to stop the thread in a certain time...
{
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
}
}
public void setText(String s)
{
this.s = s;
}
}
In this example, the main thread sets a string (every 3 seconds) and the MyThread thread prints it.
Adapt it to your needs, it shouldn't be too hard.
I had similar problem. I created an arbiter used by two threads (in your case it can be listeners thread and your task thread):
listener:
arbiter.waitConsumer();
// prepare data
arbiter.dataLoaded();
task thread:
while(true){
arbiter.waitProducer();
// consume data
arbiter.dataConsumed();
}
arbiter:
public class Arbiter {
private boolean dataLoaded = false;
public synchronized void waitProducer(){
while(!dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void waitConsumer(){
while(dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void dataLoaded(){
dataLoaded = true;
notify();
}public synchronized void dataConsumed(){
dataLoaded = false;
notify();
}}
Listener and task will synchronize themselfes against arbiters monitor. Probably you can call your arbiter queue or pipe and store date for consuming in it?