I'm developing an Android App in Java. I used a lot of library: firebase crashlytics, SQLCipher, ButterKnife etc.. The problem is: when I run the app from Android Studio, I notice the app still remain active as process, even if I close all activities. I know that there are some thread that works on background.. but I don't know how to check which thread is active, and more important, what does it do. Any idea about?
You can get what state a thread is in by using the getState() method which returns an Enum of Thread.States. A thread can only be in one of the following states at a given point in time.
NEW A Fresh thread that has not yet started to execute.
RUNNABLE A thread that is executing in the Java virtual machine.
BLOCKED A thread that is blocked waiting for a monitor lock.
WAITING A thread that is wating to be notified by another thread.
TIMED_WAITING A thread that is wating to be notified by another thread for a specific amount of time.
TERMINATED A thread whos run method has ended.
Thread t = new Thread();
Thread.State e = t.getState();
Thread.State[] ts = e.values();
for(int i = 0; i < ts.length; i++){
System.out.println(ts[i]);
}
To kill the thread , u can do this :
myService.getThread().interrupt();
NOTE : the method Thread.stop() is deprecated
EDIT : : try this
public void stopThread(){
if(myService.getThread()!=null){
myService.getThread().interrupt();
myService.setThread(null);
}
}
Related
sorry for the long edit,
I am trying to download 100k urls and I started to download using executor service as below,
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < list.size(); i++) {
try {
Callable callable = new Callable() {
public List<String> call() throws Exception {
//http connection
}
};
Future future = executorService.submit(callable);
but the above method is downloading the data only one url at a time..
and so I tried to create daemon threads (as shown below) and this method created muliple download connections (as expected) ..
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
}
while(true) {
boolean flag = true;
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for(Thread t : threads) {
if(t.isDaemon() && t.getName().startsWith("loadtest")) {
flag = false;
break;
}
}
if(flag)
break;
Thread.sleep(5000);
}
Can the same method be used for load testing on servers ?
Any other suggestions of how load testing can be done will also be of great help..
Thanks in advance !
I will hazard a guess that your ExecutorService is not working because you are calling get() on the Future instances it returns inside your loop. This mistake will indeed cause your processing to be serialized as if you had only one thread, because another task isn't submitted until the first completes.
If you really need to use Callable, don't get() the result until you are ready to block for some indefinite time as the tasks complete—and they can't complete if they haven't been submitted yet. For downloading URLs, it would be better to use Runnable, where the main thread submits URLs and then forgets about the task; the task can independently complete processing of its URL.
If you produce new tasks quickly, there's a chance you could queue up so many that you run out of memory. In that case, you can use a bounded queue and set up an appropriate rejection handler using ThreadPoolExecutor directly.
A daemon thread is a thread which does not prevent JVM to exits when all other thread finished.
I believe if you want to wait for your main thread until the time daemon threads not finished then I suggest not to use daemon thread as it is supposed not be used for that use case. You can use Thread#join to wait for your main thread.
for(int i=0; i<10; i++) {
Thread t = new Thread("loadtest " + i);
t.setDaemon(true);
t.start();
t.join(); // main or parent thread will wait util the child thread finished
}
I believe in your use case you should use normal thread instead of daemon.
Load testing is not only about "hammering" your server with requests, well-behaved load test needs to represent real user using real browser with all associated stuff like:
headers
cookies
cache
handling embedded resources (images, scripts, styles, fonts)
So I would recommend using a specialized load testing tool which are capable of representing real user as close as possible and automatically taking care of aforementioned points. Also normally the load testing tools allow you to set rendezvous points and provide a lot of metrics and charts so you will be able to see connect time, network latency, throughput, correlate increasing load with increasing response time/number of errors, etc.
I have created a dedicated thread pool to handle specific HTTP requests in Glassfish v3. I would like to get the number of inactive threads (free- not running) at any given point of time as I need to throttle the HTTP requests depending on the availability of worker threads. Is there a exposed API to get this? I don't want to submit the request to the thread pool unless threads are available.
To answer your question: As per best of my knowledge there is so no such API which can give you handy details you require, so I think you have to compute it yourself.
For solution part: java.lang.management package should help you.
java.lang.management.ManagementFactory
The ManagementFactory class is a factory class for getting managed beans for the Java platform.
You can consider using ManagementFactory which lets you get details from the JVM through exposed Java managed beans. For your case, you can use ThreadMXBean which will let you get all JVM thread information.
java.lang.management.ThreadMXBean
The management interface for the thread system of the Java virtual machine.
Read ThreadMXBean documentation and API thoroughly to understand it well, and I think in the end you can use java.lang.management.ThreadInfo object to get all the info you need.
java.lang.management.ThreadInfo
java.lang.management.ThreadInfo gets you a lot of Thread details as listed below. I don't think any other Java class can give this much info about Thread.
Thread ID.
Name of the thread.
Thread state.
The object upon which the thread is blocked due to:
waiting to enter a synchronization block/method, or
waiting to be notified in a Object.wait method, or
parking due to a LockSupport.park call.
The ID of the thread that owns the object that the thread is blocked.
Stack trace of the thread.
List of object monitors locked by the thread.
List of ownable synchronizers locked by the thread.
Below is a sample I have created for you, please note this is to get you started and a full-fledged solution cannot be provided, so please do more research about it, but I think would be helpful.
I am getting all thread states and printing them, so you can do IF-ELSE and then prepare a list of something based on state etc. and then take necessary action.
Hope this helps!
private static void getThreadInfo() {
System.out.println("Started");
ThreadMXBean managementFactory = ManagementFactory.getThreadMXBean();
long threadIds[] = managementFactory.getAllThreadIds();
for (int i = 0; i < threadIds.length; i++) {
ThreadInfo info = managementFactory.getThreadInfo(threadIds[i]);
System.out.println("Thread name = " + info.getThreadName() + " Thread id = " + info.getThreadId() + " Thread state = " + info.getThreadState());
}
System.out.println("#############");
System.out.println(Thread.currentThread().getAllStackTraces());
}
Output:
Started
Thread name = Attach Listener Thread id = 5 Thread state = RUNNABLE
Thread name = Signal Dispatcher Thread id = 4 Thread state = RUNNABLE
Thread name = Finalizer Thread id = 3 Thread state = WAITING
Thread name = Reference Handler Thread id = 2 Thread state = WAITING
Thread name = main Thread id = 1 Thread state = RUNNABLE
#############
{Thread[Finalizer,8,system]=[Ljava.lang.StackTraceElement;#1748ba4, Thread[Attach Listener,5,system]=[Ljava.lang.StackTraceElement;#7bd86d, Thread[main,5,main]=[Ljava.lang.StackTraceElement;#bdff3b, Thread[Reference Handler,10,system]=[Ljava.lang.StackTraceElement;#1bf8a41, Thread[Signal Dispatcher,9,system]=[Ljava.lang.StackTraceElement;#dd841}
I have an activity running, of course, on UI thread and there is another thread running in background and communicating with activity using Handler post method(through looper).
When screen is turned of or application is hidden it continues to work.
So I need to stop this thread in onPause method and wake it up in onResume mehtod.
In my thread I have condition to pause it or to stop.
How to can I put thread to sleep in onPause method. And wake it up after activity is again in foreground.
I can do it with one object using monitor calling wait method and than notify on this object.
But is it good approach ? Or there is another way to do this elegantly.
Sounds like a good place to use a turnstile. Initialize a Semaphore with one permit:
Semaphore turnstile = new Semaphore(1);
Make your background activity periodically pass through the turnstile like so:
turnstile.acquire();
turnstile.release();
When the foreground thread wants the background thread to pause at the turnstile, it can lock the turnstile:
turnstile.acquire();
And when the foreground thread wants that background thread to start working again, it can unlock the turnstile():
turnstile.release();
Good software engineering practice would be to wrap the whole thing up in a Turnstile class with appropriately named methods for the foreground and background threads to call. I'll leave that as an exercise for the reader.
Android suggests using services for long term background tasks, but if you're just opening a new thread that is tied to your Android lifecycle, I don't think it would be bad to use a monitor and call wait/notify. Can you be more specific with what you are doing?
This is an overview of how I would stop and resume a stopped thread. (You may want to implement runnable in yours)
class ThreadDemo extends Thread {
private Object monitor; //This is the monitor
private boolean keepRunning = true;
private Thread t;
ThreadDemo(){
System.out.println("Creating thread");
}
public void callinOnResume(){
synchronized(monitor){
monitor.notify();
}
}
public void callinOnPause(){
try {
synchronized(monitor){
System.out.println(threadName + "Waiting");
monitor.wait();
}
} catch (InterruptedException e) {
System.out.println("Thread interrupted " + e.toString());
}
}
public void run() {
System.out.println("Starting to loop.");
while (keepRunning) {
//stuff
}
System.out.println("Done looping.");
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
It is a bad practice to stop/resume a thread outside that thread. The thread must decide itself when to run and when to stop. As a result, the background thread should check periodically if its work is still needed, and the client (foreground) thread should issue some signals about that.
One way to issue signals is to form that signals as jobs of type Runnable and then execute them on a thread pool. So when the activity sleeps, it just does not issue signals.
The main problem when a background thread wants to update the UI is that the target Activity can be closed (or in the process of recreation) and the updating task fails. The AcyncTask class does not solve this problem. A correct solution is published at my Github workspace. But before to use this or another solution, think twice if you really need a background thread. The best way is not to use background thread at all, making all UI updates directly on the UI thread. Of course, if updates are taken from the network, then a background thread must be used.
Is there a way for a thread that starts a new thread to wait until the thread it started has stopped? I was thinking about using locked, but then if the thread crashes, the lock will never get release.
so when my program calls
cTurnCardOvrerConnection thread = new cTurnCardOvrerConnection("thread3", connection, mPlayerList, mPlayersMessages, lBoard);
will it wait until the thread is finished?
mPlayerList.WaitForAllPlayers();
do
{
do
{
r=GetClient();
switch(r)
{
case 0: return; // exitvon a very bad error
}
} while(r==2); // loop if it was a timeout wait for this thread to terminate.
cTurnCardOvrerConnection thread = new cTurnCardOvrerConnection("thread3", connection, mPlayerList, mPlayersMessages, lBoard);
if ( CheckTimeStamp())
break;
} while( mPlayerList.AllPlayersFinished()==false);
you can just use Thread.join().
of course, if the primary thread is just launching the secondary thread and then waiting for it to finish, there's really no use for the secondary thread (just do the work on the primary thread).
Try using a CountDownLatch.
I have tried many different ways to immediately stop a task which is started using an ExecutorService, with no luck.
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call () {
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
}
));
if(flag) { // may be true and directly cancel the task
future.cancel(true);
}
Sometimes I need to cancel the task immediately after it is started, you may be curious why I want to do this, well you may imagine a senario that a user accidentally hits the "Download" button to start a "Download Task" and he immediately wants to cancel the action because it was just an accidental click.
The problem is that after calling future.cancel(true), the task is not stopped and Thread.currentThread.isInterrupted() still returns false and I have no way to know the task was stopped from inside the call() method.
I am thinking of setting a flag like cancelled=true after calling future.cancel(true) and checking that flag constantly in the call() method, I think this is a hack and the code could be very ugly because the user can start many tasks at the same moment.
Is there a more elegant way of achieving what I want?
EDIT:
This really drives me mad. I have spent almost a day on this problem now. I will try to explain a little bit more for the problem I am facing.
I do the following to start 5 tasks, each task will start 5 threads to download a file. and then I stop all 5 tasks immediately. For all of the method calls below, i start a thread(ExecutorService.submit(task)) to make it asynchronous as you can tell from the suffixes of the methods.
int t1 = startTaskAysnc(task1);
int t2 = startTaskAysnc(task2);
int t3 = startTaskAysnc(task3);
int t4 = startTaskAysnc(task4);
int t5 = startTaskAysnc(task5);
int stopTaskAysnc(t1);
int stopTaskAysnc(t2);
int stopTaskAysnc(t3);
int stopTaskAysnc(t4);
int stopTaskAysnc(t5);
in startTaskAysnc(), I simply initiate a socket connection to remote server to get the size of the file(and this certainly is gonna take some time), after successfully getting the fileSize, I will start 5 threads to download different parts of the file. like the following(the code is simplified to make it more easy to follow):
public void startTaskAsync(DownloadTask task) {
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call () {
// this is a synchronous call
int fileSize = getFileSize();
System.out.println(Thread.currentThread.isInterrupted());
....
Future<Void> futures = new Future<Void>[5];
for (int i = 0; i < futures.length; ++i) {
futures[i] = executorService.submit(new Callable<Void>(){...});
}
for (int i = 0; i < futures.length; ++i) {
futures[i].get(); // wait for it to complete
}
}
));
synchronized (mTaskMap) {
mTaskMap.put(task.getId(), future);
}
}
public void stopTaskAysnc(int taskId) {
executorService.execute(new Runnable(){
Future<Void> future = mTaskMap.get(taskId);
future.cancel(true);
});
}
I noticed a weird behavior that after I called stopTaskAsync() for all 5 tasks, there would always be at least one task that got stopped(i.e. Thread.currentThread.isInterrupted() return true), and the other 4 tasks kept running.
And I have tried your suggestions by setting an UncaughtExceptionHandler, but nothing comes out from that.
EDIT:
The problem was solved in this link: Can't stop a task which is started using ExecutorService
Well, the javadoc of Future.cancel(boolean) says that:
If the task has already started, then the mayInterruptIfRunning
parameter determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
so it's quite certain that the thread that executes the task is interrupted. What could have happened is that one of the
... do many other things here..
is accidentally clearing the Thread's interrupted status without performing the desired
handling. If you'll put a breakpoint in Thread.interrupt() you might catch the criminal.
Another option I can think of is that the task terminates before capturing the interrupt, either because it's completed or thrown some uncaught exception. Call Future.get() to determine that. Anyway, as asdasd mentioned, it is a good practice to set an UncaughtExceptionHandler.
What you're doing is very dangerous: you're using a thread pool to execute tasks (which I'll call downloaders), and the same thread pool to execute tasks which
wait for the downloaders to finish (which I'll call controllers)
or ask the controllers to stop
This means that if the core number of threads is reached after the controller has started, the downloaders will be put in the queue of the thread pool, and the controller thread will never finish. Similarly, if the core number of threads is reached when you execute the cancelling task, this cancelling task will be put in the queue, and won't execute until some other task is finished.
You should probably use a thread pool for downloaders, another one for controllers, and the current thread to cancel the controllers.
I think you'll find solution here. The main point is that cancel method raises InterruptedException. Please check if your thread is still running after cancellation? Are you sure that you didn't try to interrupt finished thread? Are you sure that your thread didn't fail with any other Exception? Try to set up UncaughtExceptionHandler.