My Problem:
I want to run a method from a Thread, which is no Thread but might take some time to execute (e.g. waiting for server response). It is important that my none thread method is in another class (the classes are Objects which are used in other classes too).
If you do this as in the example code, the whole program will pause for 10 seconds, but I want it to continue with other program code.
Is there a good way of doing this?
My code:
MyThread.java (extends Thread)
public Foo foo;
public void run() {
foo.bar();
}
Foo.java
public void bar() {
try {
Thread.sleep(10000);
// Represents other code that takes some time to execute
// (e.g. waiting for server response)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
And a main method:
public static void main(String[] args) {
MyThread t = new MyThread();
t.foo = new Foo();
System.out.println("Starting!");
t.run();
System.out.println("Done!");
}
You don't want to call run() on the Thread, you want to call start().
Assuming MyThread extends Thread, you need to call start() not run().
Calling run() is just calling a method synchronously.
public static void main(String[] args) {
MyThread t = new MyThread();
t.foo = new Foo();
System.out.println("Starting!");
t.start(); // change here
System.out.println("Done!");
}
start() actually starts an OS thread to run your code on.
Use start() rather than run() on your thread. Or else it will be just like the main thread calling a method of another thread which means you are calling wait() on the main thread itself.
don't call run() method directly.
call start() method instead of run() method.
when call run() method directly
this thread go to main stack, and it run one by one.
class MyThread extends Thread{
public Foo foo;
public void run() {
foo.bar();
}
}
class Foo{
public void bar() {
try {
boolean responseCompleted = false;
boolean oneTimeExcution = false;
while(!responseCompleted){
if(!oneTimeExcution){
// Represents other code that takes some time to execute
oneTimeExcution = true;
}
if( your server response completed){
responseCompleted = true;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("Starting!");
t.start();
System.out.println("Done!");
}
Related
This question already has answers here:
How to start anonymous thread class
(9 answers)
Closed 5 years ago.
This thread does not execute when I run the program. I'm wondering if there's something wrong with the code.
public static void writeToFileAsync(final String saveState, final String fileName) {
new Thread() {
public void run() {
try {
writeToFile(saveState, fileName);
} catch (IOException ex) {
}
start();
}
};
}
Also, why does NetBeans want me to put that semicolon next to the second curly brace after the start() call?
Start a thread
Your thread will only start if you call the start method explicitly. Here is the documentation Thread#start. The start method will then internally invoke the run method of your Thread.
Your code could then look like this:
public static void writeToFileAsync(final String saveState, final String fileName) {
// Create the thread
Thread fileWriter = new Thread() {
#Override
public void run() {
try {
writeToFile(saveState, fileName);
} catch (IOException ex) {
// Do nothing
}
}
};
// Start the thread
fileWriter.start();
}
And you probably want to remove the start(); call inside your run method.
Semicolon
You need the ; after the Thread creation because you are using an assignment:
Thread fileWriter = new Thread() { ... };
The concept you are using here is called anonymous class. Basically it is the same as if creating a new class like:
public class FileWriter extends Thread {
#Override
public void run() {
...
}
}
And then using it like:
Thread fileWriter = new FileWriter();
However an important difference is that your anonymous class has access to your local variables (the scope of that method). And that it is anonymous, so it's like a small single-time usage class.
Your call to the start method cannot be inside the body of your thread. You can do this:
new Thread() {
public void run() {
try {
writeToFile(saveState, fileName);
} catch (IOException ex) {
}
}
}.start(); // call the start method outside the body of you thread.
And about the semicolon, you are creating an Anonymous Class and that is its syntax:
Because an anonymous class definition is an expression, it must be
part of a statement... (This explains why there is a semicolon after
the closing brace.)
A thread simply works this way. Below is a piece of code where a thread is created as an anonymous inner type where the run method is overrided. Then by calling the start method , it automatically called the overrided run method.
public class ThreadTest {
Thread t = new Thread(){
public void run() {
System.out.println("thread is running");
};
};
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
threadTest.t.start();
}
}
I have just seen problem in my below code in isAlive method , it will return false even thread.start() method has been called, even i also tried to add some sleep in main thread as well as my thread object but still it gives same behavior.
public class ThreadBehaviour implements Runnable {
private Thread t;
ThreadBehaviour() {
t = new Thread();
t.setName("hello");
}
public void start() throws InterruptedException {
if (!t.isAlive()) {
t.start();
//Thread.currentThread().sleep(1000L);
//t.sleep(3000l);
System.out.println(t.getName() + " Running....." + t.isAlive());// why is Alive is false here?
}
}
public static void main(String args[]) throws InterruptedException {
ThreadBehaviour myThread = new ThreadBehaviour();
myThread.start();
}
#Override
public void run() {
t.run();
}
}
Your Thread that you made does nothing, so it instantly finishes and dies.
Consider this:
t = new Thread(() -> {
while (true) {
System.out.println("I'm running...");
}
});
and try again.
Read the java doc
isAlive();
Tests if this thread is alive. A thread is alive if it has been
started and has not yet died.
You only instantiate in constructor without started. So the thread is not started.
This question already has answers here:
How to start anonymous thread class
(9 answers)
Closed 9 years ago.
public Thread thread = new Thread();
public void start() {
running = true;
thread.start();
}
public void run() {
while(running) {
System.out.println("test");
try {
thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
My problem is that the program will not print out "test" nor will it seem to loop despite 'running' being true. Is there a way I can continuously loop in the run method?
You haven't actually asked run() to be called. All you've done is declare a run() method unrelated to the Thread.
Put your run() method in a Runnable and pass that to the Thread.
public Thread thread = new Thread(new Runnable() {
public void run() {
while (running) {
System.out.println("test");
try {
thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
The problem appears to be that you aren't running the run method that you think you're running in the thread.
First, you've created a Thread called thread. In your class's start method, you set running to true and call thread.start(). But that just calls Thread's run() method, which does nothing.
public void run()
If this thread was constructed using a separate
Runnable run object, then that Runnable object's run method is called;
otherwise, this method does nothing and returns.
You aren't calling your own run method.
You have created a run method. I can't see your class definition here, but I'm assuming that your class implements Runnable. You need to send an instance of your class as an argument to the Thread, by using the Thread constructor that takes a Runnable. Then the Thread will know to run your Runnable's run() method.
Well you need to call start() to start the thread. Otherwise neither running will be true
nor thread.start() get executed. Well i can guess you were intended to do something like this:
class MyTask implements Runnable
{
boolean running = false;
public void start() {
running = true;
new Thread(this).start();
}
public void run() {
while(running) {
System.out.println("test");
try {
Thread.sleep(1000);
// you were doing thread.sleep()! sleep is a static function
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
new MyTask().start();
}
}
The following code blocks in synchronized sync() method before calling plain() method. Why is this so, shouldn’t the intrinsic lock block call to synchronized methods only – for example this behavior would have been fine if plain() was synchronized as well.
As the monitor concept that java uses is applicable to synchronized methods/blocks only – it by definition should not affect execution of non synchronized code. Is this always the case or is this behavior JVM implementation specific.
public class Main {
public static void main(final String[] args) {
final Main main = new Main();
new Thread(new Runnable() {
#Override
public void run() {
main.sync();
}
}).run();
main.plain();
}
public synchronized void sync() {
try {
System.out.println("sleeping...");
Thread.sleep(2000);
System.out.println("out...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void plain() {
System.out.println("plain...");
}
}
Output:
sleeping...
out...
plain...
You should call start() rather than run() on the new Thread. Calling run() will execute the runnable's run method in the current thread, rather than starting a new thread to run it.
Supposed I have a class MyThread, which implements Runnable with a method dosomething():
class MyThread implements Runnable{
Object dosomething(Parameter p){ ... }
run(){...};
}
If I do:
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
will dosomething be executed on myThread or in the main Thread?
How can I start the execution of dosomething on myThread from the main Thread and retrieve the returned Object?
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
If you do that it won't compile: you're trying to assign the result of a void method, void run(), to an object of type MyThread.
Implementing runnable and calling run() will not cause the code to be executed in a separate thread unless you pass it to another thread (i.e. Tread t = new Thread(my);)
How can I start the execution of dosomething on myThread from the main Thread and retrieve the returned Object?
You do that by storing the result of doSomething() in a location where you can access it later.
class MyClass
{
public Object doSomething()
{
// return the object
return new Object();
}
}
class MyRunnable implements Runnable
{
private final MyClass _mc;
private final object _lock;
private final List<object> _results;
public MyRunnable(MyClass mc, List<object> results, object lock)
{
_mc = mc;
_lock = lock;
_results = results;
}
public void run()
{
synchronized(_lock)
{
_results.add(_mc.doSomething());
}
}
}
So now in main:
void main(){
MyClass mc = new MyClass();
List<object> results = new List<object>();
object lock = new object();
// Execute your thread and wait for it to complete
Thread t = new Thread(new MyRunnable(mc, results, lock ));
t.start();
t.join();
// Get the results
for(object result:results)
{
// do something with the result
}
}
This should give you an idea of what you're doing "wrong." A more realistic example would be if you spawn multiple threads, run them concurrently and then join on all of them until they all complete.
Sounds like you may want to consider Callables and Futures.
There's a decent explanation at http://www.vogella.de/articles/JavaConcurrency/article.html#futures
You can use delegate, for example.
new MyThread(callWhenFinishObject)
It'll be executed on the main thread, since it's that thread that calls the method. If you want dosomething to run in the separate thread, have it called within run() and store the result in a myThread field for later retrieval.
You might want to check class Future or other stuff in java.util.concurrent for some convenient way of waiting for the result to become available.
EDIT: if dosomething should only run until some condition is satisfied that must be flagged in the main thread, have run() block until the main thread somehow signals the other thread that it's okay to go on.
EDIT 2: here, someone confirm this is what's being asked:
package threadtest;
public class Main {
public static void main(final String[] args) {
final MyThread otherThread = new MyThread();
System.out.println("Main thread: I'm gonna start the other thread now...");
otherThread.start();
System.out.println("Main thread: there, hope it does well.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: I'm gonna do some stuff in the meantime...");
try {
Thread.sleep(200); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: maybe clean up the kitchen.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: does other thread have something for me yet?");
if(otherThread.getResult() == null)
System.out.println("Main thread: nope, not yet.");
try {
Thread.sleep(500); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: oh crap! I forgot to tell it that it may execute its method!");
otherThread.allowToExecute();
System.out.println("Main thread: phew... better keep checking now before it gets angry.");
while(otherThread.getResult() == null) {
try {
Thread.sleep(100); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Main thread: there we go, it gave me a result. Rest in peace, other thread...");
}
private static class MyThread extends Thread {
private boolean mayExecuteDoSomething = false;
private Object result = null;
#Override
public void run() {
System.out.println("Other thread: whoa, someone started me!");
while(!mayExecuteDoSomething) {
try {
Thread.sleep(100); //I'm gonna sleep for a bit...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Other thread: alright, I'm allowed to execute my method!");
result = doSomething();
System.out.println("Other thread: there, did it. I'll just call it quits now.");
}
public void allowToExecute() {
mayExecuteDoSomething = true;
}
private Object doSomething() {
return new Object();
}
public Object getResult() {
return result;
}
}
}
This is a very crude approach to the issue. The basic concepts are there, though. In reality, you'd want to use stuff like Callable and Future for proper asynchronous computation.
That is not possible.
When you create a thread, it runs the code in run() and exits.
There is no way to inject code into a different thread; that would break the core execution model. (Within a thread, your code runs sequentially, with nothing in between)
If you want to, you can create a thread that listens for callback (Runnable instances) in a queue and executes them (like a message loop).
This is how the UI thread works.
Also, you aren't actually startign a thread; you need to write new Thread(someRunnable).start()