I create a thread to process some queue data. Inside the thread there is a unlimited while loop. when loop is working, the interface always freezing.
Im confused about this, I've created the thread, but why it still freezing ??
Thread queue = new Thread(new Runnable() {
public void run() {
while(true) {
...
}
}
});
queue.start;
Any solution for this problem ?
Its not just your interface slowing down, in fact your phone will be too because you are consuming (unnecessarily wasting) all the processing powers in a while loop. For better approach, use Handler and/or AsyncTask or at least use Thread.sleep inside while-loop in your thread.
Related
I have thread which contains a loop
while(isRunning){
}
isRunning is a Boolean variable with the value true, when some clicks on a button it gets false and so it leaves the loop and the run() function of the thread.
I want to create another button that on click it will reenter the run() function.
I am not sure if when I leave the run() function the thread dies or just stops.
I have tried using thread.run() but it didnt work.
Also I have looked for an answer in other's people questins about this matter but nothing seemed to help me. Thanks for the help
When a thread is finish processing it's code, There's no way of restarting it. You can either:
Create a new thread and pass the Runnable to that thread.
If you need to use that run() method often, use an Executor. You can use Executors.newSingleThreadExecutor(), which will supply you with a worker thread. (Reusable thread).
class Example {
static ExecutorService executor = Executors.newSingleThreadExecutor();
static Runnable run = new Runnable() {
public void run() {
}
};
public static void main(String[] args) {
//anytime you wanna run that code..
executor.execute(run);
}
}
If your thread runs to its end, it stops.
It will remain there for you to collect its return status until the thread is cleaned up.
To restart within the same thread, you need an extra control flow.
For instance:
while (restarted) {
while (isRunning) {
}
// Wait for a restart or end click
}
That is what so called worker threads in a thread pool do, which are intended for maximum performance.
But logically, you will probably simply want to create a new thread object and start that one.
new Thread(p).start();
Please read through java concurrency tutorial.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
Just Maybe, guarded blocks might be useful for your case but your case is a little vague to recommend anything specific.
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
I have a code in Android, which is resource intensive. It processes a bitmap and then saves it to the sdcard.
Since running it on the main thread took a lot of time, I did it like this:
new Thread(new Runnable() {
public void run() {
//do work
}
}).start();
But, I found that if I invoked this piece of code before the thread had fully executed, the previous thread just got deleted and overwritten with the new task. The sdcard showed only the last image.
So I wrote a static thread as :
Thread t=new Thread(new Runnable() {
public void run() {
//do work
}
};
But, t.start() cannot be called multiple times. (llegalThreadStateException)
What should I do to overcome this?
Spawning a second thread using the code you gave above will work and run both threads in parallel. Something else must be going on to stop it working.
Make sure you have a try-catch around your do work and log any errors. Are both threads trying to write to the same file and the second one failing because it cannot?
For the actual thread you cannot start a thread again once it has exited, instead you need to keep the thread alive and run it in a loop. The thread should go to sleep when it is no longer needed, waiting for a message to arrive giving it new work to do. This can be done using something like a BlockingQueue.
Alternatively rather than managing threads yourself you can use something like a ThreadPoolExecutor and keep sending your Runnables to that.
I am working in java android platform. I am creating a child thread from main thread. I want to stop child thread as my requirments. My child thread has simple function which doesn't have any loop. I want to kill child thread and free resources it is using, whenever I want. I searched for it and I found inturrupt() function. My thread is:
public class childThread implements Runnable{
public void run() {
firstFunction();
secondFunction();
}
}
Main thread has this code to start above thread:
Thread tChild;
tChild = new Thread(new childThread(), "Child Thread");
tChild.start();
My run() function is calling function like this. How to I use interrupt() in this? Please tell me any other way to kill child thread and deallocating its resources.
With a thread's cooperation, you can stop that thread using any method it supports. Without a thread's cooperation, there is no sane way to stop it. Consider, for example, if the thread holds a lock and has put a shared resource into an invalid state. How can you stop that thread without its cooperation?
You have two choices:
Code your threads so that they don't do work that you don't want them to do. Code them so they terminate themselves when they have no work to do. That way, they won't need some other thread to "reach in" from the outside.
Code your threads so that they provide some way to be told that they should terminate and then they terminate cleanly.
But those are your choices -- it can't work by magic.
Think of a thread doing work like your sister borrowing your car. If you need the car back, you need your sister's cooperation to get it back. You can either arrange is so that she comes back when you need the car by herself or you can arrange is so that you tell her when you need the car and then she comes back. But you can't change the fact that she has to know how to bring the car back or it won't get back.
Threads manipulate process resources and put them into invalid states. They have to repair things before they terminate or the process context will become corrupt.
As you don't have any loop, where check Thread.interrupted() value, and I assume that your firstFunction(); secondFunction();, do a heavy work, you will have to check in the appropiate points inside functions firstFunction(); secondFunction(); the condition Thread.interrupted(), and finish the method if true. I know that you don't have loops, but conceptually would be something like this,
Runnable runnable = new Runnable() {
private int counter;
public void run() {
while(true){
System.out.println(">> Executing " + counter++);
if(Thread.interrupted()){
break;
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
Thread.sleep(10 * 1000);
thread.interrupt();
Just call interrupt on tChild object and it will interrupt your child thread
Thread tChild;
tChild = new Thread(new childThread(), "Child Thread");
tChild.start();
//...
tChild.interrupt();
Your child thread will need to check Thread.interrupted() on a regular basis and exit if it returns true.
It doesn't matter if your code has loops or not. You just need to choose various points in your code execution path to see whether cancellation is necessary.
Surround your code with try catch.
Catch for InterruptedException then come out . If there are loops, put the catch statement outside the loop / break the loop if the catch is inside.
Runnable runnable = new Runnable() {
public void run() {
try {
while(true) {
// your code
}
}(InterruptedException e) {
// It comes out
}
}
I'm "converting" a C++ program (a Borland "Component", to be more precise), which uses a Serial port, to Java.
That program uses a thread to listen to the serial port, and raises an event when one of the given "event chars" is received (it could be the Carriage Return, ACK, NACK...) or when a userd-defined number of chars are received.
While trying to convert it in Java, I learnt a bit about Threads, make it half-working.
I still have to understand how to raise an event from the listening thread to the main thread... and then i learned the existence of Executors, which seems to be the right way to go, since the user could close, reopen, or change the port multiple times and creating a new thread each time seems to be a bad practice.
So, before struggling for days in the Java concurrency sea, after so much work spent on "raw" Threads, I would ask for an advice, and perhaps a little sample.
What kind of object (i see there's various kind of Executors) should i use to have a serial listener which:
is able to throw an event to the main thread to pass the received chars array
can be suspended and restarted (and that can point to a different input stream while suspended... i mean that i could call some of its method while suspended)
it will be destroyed when not needed (the user could choose to use a socket instead, so the listener will be not needed anymore)
?
I really don't know if some of these points are depending on the object i'll choose, so i've listed them all just to avoid to re-do everything another time 'cause i was not clear.
Thanks.
If you have some main thread that just must receive the events from other threads (much like a server socket does), some blocking queue may be a solution. The main thread could call the takeLast in a loop - this will suspend it until any other thread calls putFirst, offering a value to take for the same queue. (SynchronousQueue will stall the offering thread till the main thread is ready or alternatively ArrayBlockingQueue supports a queue of the given size).
With such setup, the main thread cannot also be a GUI thread. Use invokeAndWait if you need to touch interface components like labels or buttons from it.
final BlockingQueue q = new ArrayBlockingQueue(3);
new Thread() {
public void run() {
while (have_some_messages()) {
q.putFirst("Hey!");
}
}
}.start();
new Thread() {
public void run() {
while (also_have_some_messages()) {
q.putFirst("Boo!");
}
}
}.start();
// Main thread will print both Hey and Boo:
while (must_keep_running()) {
Object serveIt = q.takeLast();
System.out.println(serveIt);
}
In case the main thread is a Swing thread (you say JFrame with Swing controls), add a button there to start the servicing thread:
Runnable service = new Runnable() {
public void run() {
try {
while (must_keep_running()) {
Object serveIt = q.takeLast();
System.out.println(serveIt);
}
} finally {
// Re-enable the start button when the service thread exits:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bStart.setEnabled(true);
}
});
};
}
};
JButton bStart = new JButton("Start ..");
bStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Thread(service).start();
bStart.setEnabled(false);
}
}
});
I would make the port-liestening thread based on a singleton with perhaps some static (synchronized!) accessors.
A good interface for communicating between threads in your case would be a Listener/Observer pattern - it should be versatile enough to solve your problem.
Since you are a beginner in Java, one hint: start without threads, just use non-blocking IO. Then - only after everything is working properly - consider using multiple threads. And do it only if you have performance problems.
I have question about the Java threads. Here is my scenario:
I have a thread calling a method that could take while. The thread keeps itself on that method until I get the result. If I send another request to that method in the same way, now there are two threads running (provided the first did not return the result yet). But I want to give the priority to the last thread and don't want to get the results from the previously started threads. So how could I get rid of earlier threads when I do not have a stop method?
The standard design pattern is to use a local variable in the thread that can be set to stop it:
public class MyThread extends Thread {
private volatile boolean running = true;
public void stop() {
running = false;
}
public void run() {
while (running) {
// do your things
}
}
}
This way you can greacefully terminate the thread, i.e. without throwing an InterruptedException.
The best way really depends on what that method does. If it waits on something, chances are an interrupt will result in an InterruptedException which you handle and cleanly exit. If it's doing something busy, it won't:
class Scratchpad {
public static void main(String[] a) {
Thread t = new Thread(new Runnable() {
public void run() {doWork();}
});
t.start();
try {
Thread.sleep(50);
} catch (InterruptedException ie) {}
t.interrupt();
}
private static void doWork() {
for ( long i = 1; i != 0; i *=5 );
}
}
In the case above, the only viable solution really is a flag variable to break out of the loop early on a cancel, ala #inflagranti.
Another option for event-driven architectures is the poison-pill: if your method is waiting on a blocking queue for a new item, then you can have a global constant item called the "poison-pill" that when consumed (dequeued) you kill the thread:
try {
while(true) {
SomeType next = queue.take();
if ( next == POISON_PILL ) {
return;
}
consume(next);
}
} catch //...
EDIT:
It looks like what you really want is an executor service. When you submit a job to an executor service, you get back a Future which you can use to track results and cancel the job.
You can interrupt a Thread, its execution chain will throw an InterruptedException most of the time (see special cases in the documentation).
If you just want to slow down the other thread and not have it exit, you can take some other approach...
For one thing, just like exiting you can have a de-prioritize variable that, when set, puts your thread to sleep for 100ms on each iteration. This would effectively stop it while your other thread searched, then when you re-prioritize it it would go back to full speed.
However, this is a little sloppy. Since you only ever want one thing running but you want to have it remember to process others when the priority one is done, you may want to place your processing into a class with a .process() method that is called repeatedly. When you wish to suspend processing of that request you simply stop calling .process on that object for a while.
In this way you can implement a stack of such objects and your thread would just execute stack.peek().process(); every iteration, so pushing a new, more important task onto the stack would automatically stop any previous task from operating.
This leads to much more flexible scheduling--for instance you could have process() return false if there is nothing for it to do at which point your scheduler might go to the next item on the stack and try its' process() method, giving you some serious multi-tasking ability in a single thread without overtaxing your resources (network, I'm guessing)
There is a setPriority(int) method for Thread. You can set the first thread its priority like this:
Thread t = new Thread(yourRunnable);
t.start();
t.setPriority(Thread.MIN_PRIORITY); // The range goes from 1 to 10, I think
But this won't kill your thread. If you have only two threads using your runnable, then this is a good solution. But if you create threads in a loop and you always sets the priority of the last thread to minimum, you will get a lot of threads.
If this is what is application is going to do, take a look at a ThreadPool. This isn't an existing class in the Java API. You will have create one by yourself.
A ThreadPool is another Thread that manages all your other Threads the way you want. You can set a maximum number of running Threads. And in that ThreadPool, you can implement a system that manages the Thread priority automatically. Eg: You can make that older threads gain more priority, so you can properly end them.
So, if you know how to work with a ThreadPool, it can be very interesting.
According to java.lang.Thread API, you should use interrupt() method and check for isInterrupted() flag while you're doing some time-consuming cancelable operation. This approach allows to deal with different kind of "waiting situations":
1. wait(), join() and sleep() methods will throw InterruptedExcetion after you invoke interrupt() method
2. If thread blocked by java.nio.channels.Selector it will finish selector operation
3. If you're waiting for I/O thread will receive ClosedByInterruptException, but in this case your I/O facility must implement InterruptibleChannel interface.
If it's not possible to interrupt this action in a generic way, you could simply abandon previous thread and get results from a new one. You could do it by means of java.util.concurrent.Future and java.util.concurrent.ExecutorService.
Cosider following code snippet:
public class RequestService<Result> {
private ExecutorService executor = Executors.newFixedThreadPool(3);
private Future<Result> result;
public Future<Result> doRequest(){
if(result !=null){
result.cancel(true);
}
result = executor.submit(new Callable<Result>() {
public Result call() throws Exception {
// do your long-running service call here
}
});
return result;
}
}
Future object here represents a results of service call. If you invoke doRequest method one more time, it attempts to cancel previous task and then try to submit new request. As far as thread pool contain more than one thread, you won't have to wait until previous request is cancelled. New request is submitted immediately and method returns you a new result of request.