I have 2 java class "LegacyDAO" and "NewDAO" implementing Runnable. In an another class "Test" we create one object of each LegacyDAOObj and NewDAOObj.
Class Test {
public static void main(String args[]) {
LegacyDAO legacyDAOObj= new LegacyDAO();
NewDAO newDAOObj= new NewDAO();
Thread legacyDBThread= new Thread(legacyDAOObj);
Thread newDBThread= new Thread(newDAOObj);
}
}
Is there any relation between legacyDBThread and newDBThread ?
If I want newDBThread to execute some code and then wait for legacyDBThread to finish and then continue running. How can this be achieved ?
wait() and notify() API is helpful here. you can share some objects in two class and use wait-notify on these shared objects to sync two thread.
You can use countdown latch. Create a count down latch with count one, pass it to legacyDAOObj. After the logic executed in legacyDAOObj, count down the latch. Till the logic is executed in legacyDAOObj, newDAOObj awaits.
If you just want to wait for a thread to end, use Thread#join(), it seems to be the easiest way to achieve what you want.
CountdownLatch will be your best bet. Your newDaoObj will continue in main thread once legacyDaoObj finishes.
public static void main(String[] args) {
CountDownLatch start =new CountDownlatch(1);
LegacyDAO legacyDAOObj= new LegacyDAO();
NewDAO newDAOObj= new NewDAO();
new Thread(new Worker(legacyDAOObj)).start();
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
newDAOObj.doSomething();
}
public static class Worker implements Runnable{
LegacyDAO dao;
public Worker(LegacyDAO dao) {
this.dao = dao;
}
#Override
public void run() {
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
dao.doSomething();
start.countDown();
}
}
Related
is thisgood practice to creating a new thread inside Runnable?
public class ExampleThread Implements Runnable{
public void run() {
try {
//Some functions
}
catch (IOException e) {
}
new Thread() {
public void run()
// some functions
}}.start();
}
It's kind of wrong in this case because ExampleThread is not really a thread, the first try catch block will be executed in the main thread.
Technically speaking, Runnable is just an interface so nothing wrong I guess.
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!");
}
I have myThread.wait() that is in synchronzed(myThread) block. And I have Myrunner that implements runnable. I would like to tell notify() from myRunner, but it is not monitor object. Is it possible to get handle of myThread from myRunnable to make notify? Is there any other solution? Extend myRunnable from Thread and run it is not good for some reasons related on my code specific.
public class ThreadMain {
public Thread reader;
private class SerialReader implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep(3000);
synchronized(this) {
System.out.println("notifying");
notify();
System.out.println("notifying done");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new Thread(new SerialReader());
}
public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
synchronized(d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
Both threads should synchronize using the same object. Also, you should really not use an existing object to syncronize, but create a object to be used explicitly for synchronization, like
Object lock = new Object();
Also see https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Do+not+synchronize+on+objects+that+may+be+reused
If the lock is to be used to interact with your thread, you can put it in the thread and provide a getter for anyone to use it.
To notify() a wait()ing thread you much have a reference to the object it is wait() on and you must be able to acquire a lock on it. I suggest you also change a state which notifying and you check that state change in a loop when wait()ing.
The only other option is to change the code of the waiting thread.
I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks
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()