thread = new Thread()
{
#Override
public void run() {
while(!requestedToExit)
{
SystemClock.sleep(3000);
Log.d("debug", "in");
}
}
};
So a button got an event, Each time I click on it it's start the thread (if the previous thread is not alive).
So I tried use thread.start() but it throw thread already started. I tried .run(), nothing happens, I also tried each time I click on the button, and it's possible to run it again, create a new thread and start it : nothing.
Some ideas ?
Using Runnable :
r= new Runnable(){
public void run() {
while(!requestedToExit)
{
Log.d("debug", "in");
SystemClock.sleep(3000);
}
}
};
Then I use in my listener :
thread = new Thread(injection);
thread.start();
But I only see the debug the first time, he never enter into it after.
Thanks in advance
From the JavaDoc -
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.
Instead, use java.lang.Runnable and create a new thread to run it when you have to.
What you need to do is:
Runnable r = new Runnable() {
public void run() {
....
}
};
Then, when you want to start it:
Thread t = new Thread(r);
t.start();
You need to always create a new thread to run that one runnable.
Related
I am using a thread to get an id from my database. Once the thread has finished running I need to use that id in another thread to get a list of items. Once that thread has finished I use the list of items to populate a spinner. The problem I am encountering is that it is populating the spinner before the thread has returned the list of items. How can I make it so the spinner doesn't get populated until the thread has finished running?
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
new Thread(new Runnable() {
#Override
public void run() {
String bookName = existingBooks.get((int) spinner.getSelectedItemId());
Book myBook = AppDatabase.getInstance(getContext()).bookDAO().getBookByTitle(bookName);
long book_Id = myBook.getBook_id();
existingCountDates = AppDatabase.getInstance(getContext()).countDAO().getCountDatesInBook(book_Id);
List<Count> Counts = AppDatabase.getInstance(getContext()).countDAO().getAllCounts();
Log.e("Dates", existingCountDates.toString());
Log.e("All Counts", Counts.toString());
}
}).start();
//TODO: FIX THIS ISSUE
Log.e("Problem:", "This gets called before the thread finishes. Not sure how to fix it");
str_adapter.clear();
for (int i = 0; i < existingCountDates.size(); i++) {
str_adapter.add(existingCountDates.get(i));
}
str_adapter.notifyDataSetChanged();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
//TODO: DISABLE OTHER DROPDOWN MENUS?
}
});
You can use another thread and wait previous thread till finish using thread.join(). bu better version is use ExecutorServices such as for instance the ThreadPoolExecutor.
CODELAB
I am not sure whether this will help you or not. But you can use a bool variable to check whether the thread has finished its work.
bool flag = false;
new Thread(new Runnable() {
#Override
public void run() {
//statements
flag = true;
}
}).start();
while(flag != true);
//statements to be executed after completion of thread.
NOTE: Make sure execution never goes to infinite loop.
How can I make it so the spinner doesn't get populated until the thread has finished running?
There are a couple of ways to do that. The easiest might be to get an ExecutorService which is usually recommended as opposed to creating a Thread "by hand". This also allows you to return a value from your job in which case you submit a Callable<?> instead of a Runnable.
ExecutorService threadPool = Executors.newFixedThreadPool(1);
...
Future<Void> future = threadPool.submit(new Runnable() {
public void run() {
...
}
});
// wait for this job to finish
future.get();
...
// when you are done with the pool you need to shut it down
threadPool.shutdown();
You can also start a thread and then join() with it. That waits for the thread to finish.
Thread thread = new Thread(new Runnable() { ... });
thread.start();
// now we can do stuff while the thread runs in the background
...
// wait for the thread to finish before returning
thread.join();
...
The get() method or the join() method also means that the existingCountDates or anything else that was modified inside of the job will be updated in the caller's memory appropriately.
i am writing code from online to create a chat application. After trouble shooting my program to find out why it is not working I have discovered that the code inside my run method here is not being reached. here is the snippet of code
public void listen()
{
listen = new Thread("Listen") {
public void run()
{
writeMessage("Working in here");
while (true) {
String message = client.receive();
if (message.startsWith("/c/")) {
client.setID(Integer.parseInt(message.substring(3, message.length())));
writeMessage("Successfully connected to server" + client.getID());
}
}
}
};
}
It is reaching the listen method itself, because if i use the write message command before i declare the thread, it prints out the message for me, any idea from looking at this why it will not enter any further?
Thanks
Calling start() on your Thread would do it:
public void listen()
{
listen = new Thread("Listen") {
public void run()
{
writeMessage("Working in here");
while (true) {
String message = client.receive();
if (message.startsWith("/c/")) {
client.setID(Integer.parseInt(message.substring(3, message.length())));
writeMessage("Successfully connected to server" + client.getID());
}
}
}
};
listen.start(); // <-- Add this line
}
Also, you typically don't want to extend Thread (which you are doing here with an anonymous class). Usually you'll want to create a Runnable and pass that to Thread's constructor instead:
Runnable r = new Runnable() {
#Override
public void run()
{
// Do some work here
}
};
Thread listen = new Thread(r, "Listen");
listen.start();
Or even better, use an Executor, there aren't many good reasons to create your own Thread objects.
Certainly working with appropriate Execotor or even better ExecutorService is more appropriate way of working with threads today. Read about it here. But if you insist on working the old way then you need to invoke start() method of your thread. Methods start() and run() do the same thing, only run() execute your thread sequentially i.e. in the same thread where you invoked it and start() actually starts a new thread where your code is executed which is what you wanted in the first place
I'm using GCM to receive message from google server. when the message has received at device ; it starts a 1-minute thread, and if no other message has come until 1min it will show the analog clock on screen. but if before 1 minute the message has come: here's the problem how can reinitialise the thread from zero to measure again 1min???
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
}
handler.post(new Runnable() {
#Override
public void run() {
analogClock.setVisibility(View.VISIBLE);
lblMessage.setText("");
}
});
}
});
t.start ();
// Schedule task to terminate thread in 1 minute
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.schedule (
new Runnable(){
#Override
public void run (){
t.interrupt();
}
} , 1, TimeUnit.MINUTES);
}
Simplest solution seems to be to keep a rest boolean in the thread - when you scheduled runnable executes you can either terminate the thread or reschedule this runnable for a new minute in the future.
You can't exactly reuse a thread in Java but you can plan NOT to terminate your thread unless it is appropriate.
In Java you really can't reuse threads (see here). Just create another one.
To cancel previous task you can cancel the ScheduledFuture using cancel(boolean):
ScheduledFuture<?> future = exec.schedule (
new Runnable(){
#Override
public void run (){
t.interrupt();
}
} , 1, TimeUnit.MINUTES);
}
...
future.cancel(true); // Or false, I don't know your exact requirements here
Anyway in your case and in Android you're better off with AsyncTask instead of Thread.
I'm starting a thread which loops indefinitely until a certain event occurs. The problem is, I want to start this thread, and then return to the normal execution of my program. However, after starting the thread, the code seems to get stuck.
Code:
public void init()
{
Runnable thread = new Runnable()
{
public void run()
{
while(something)
{
//do something
}
}
};
System.out.println("Starting thread..");
new Thread(thread).run();
System.out.println("Returning");
return;
}
When I start this, I get the output "Starting thread" but I don't get "returning" until the conditions for the while loop in the run() stop being true.
Any ideas how I can make it work asynchronously?
Use start rather than run to start a Thread. The latter just invokes the run method synchronously
new Thread(thread).start();
Read: Defining and Starting a Thread
You may try this in your code:-
new Thread(thread).start();
like:-
public void init()
{
Runnable thread = new Runnable()
{
public void run()
{
while(something)
{
//do something
}
}
};
System.out.println("Starting thread..");
new Thread(thread).start(); //use start() instead of run()
System.out.println("Returning");
return;
}
You want to call new Thread(thread).start() instead of run().
Are you sure about your approach? You say:
The thread should loop indefinitely until certain event occurs.
that's an enormous loss of computational resource, the program is principally bound to get slow & fail. You may want to put the thread in wait() mode and catch InterruptedException to wake it up upon occurrence of your event of interest. If this preliminary understanding of what you are trying to accomplish is true then Id' strongly suggest you to revise your approach. Computing resource is expensive, don't waste it in relentless looping.
while we want to execute 2 Runnables :
executor.execute(new Runnable1());
executor.execute(new Runnable2());
it is unknown that which Runnable will start to be executed first? but I want Runnable1 be started for execution first. how to do that?
Why not create one runnable which just runs Runnable1() then Runnable2()? If you don't want them to execute in parallel, don't submit them both to an executor separately...
For example:
executor.execute(new Runnable() {
#Override public void run() {
new Runnable1().run();
new Runnable2().run();
}
});
Of course, you should consider what you want to happen if Runnable1 throws an unchecked exception - do you want Runnable2 to run or not?
EDIT: With your updated requirements, it sounds like really you want your second runnable to only start when your first runnable has reached a particular point (e.g. a socket has been created and is listening for connections). You quite possibly want to put some sort of hook in that code, so that you can start the second runnable when you get there:
// Somewhat pseudo-code...
Server server = new Server();
server.onStartedListening(new Runnable() {
#Override public void run() {
executor.execute(new ClientConnection());
}
});
executor.execute(server);
Inside your Runnable2() code check for status of Runnable1.completed
Where in Runnable1 define a static boolean completed = false; and make it true once the execution is finished in Runnable1