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
Related
Ok, guys so my teacher uses this code to start a thread if a thread is not already active. But i have been taught that to run threads no matter if its runnable or extending thread, you start it by the start method and not run. But in this case he starts it with run, why is that?
public void start2(Runnable r) {
if (thread == null) {
thread = new Thread(new Runnable() {
public void run() {
r.run();
thread = null;
}
});
thread.start();
}
}
Your teacher starts thread with thread.start() . He just implemented the runnable interface inside the Thread object initialization which is the absolutely correct approach.
A more modern approach would be to use an Executor to run the thread:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
});
You have a better control of the thread:
Can retrieve some result (with futures)
Know if your thread is over (executor.isTerminated())
Request/force a shutdown (executor.awaitTermination()/executor.shutdownNow()).
These functionalities are not natively supported by the thread.start() that your teacher shows you (which is, by the way, a good way to launch a thread).
For more about Executors, I advice this excellent tutorial.
The r.run(); part in your code is just a method call to your Runnable r input parameter, which will be an implementation of the Runnable interface.
This does not start a thread
It's just a method call that is executes the input's implementation of Run method.
It will execute just like any other method.
Then, the actual thread will start at thread.start();
Long answer:
What is happening here is, first checking the thread variable.
If its null then initialize a new Thread with an anonymus class thread = new Thread(/*here --> */new Runnable() {.... and implementing the run() method.
Inside the run() there is a call, made to the outer method's input param, called Runnable r with r.run(); then set the thread variable to null.
Just outside of the if statement, the teacher starts the thread with thread.start();.
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.
I cannot seem to find a good answer to my problem:
Suppose I have a certain amount of runnables of the form
public class NeverendingRunner implements Runnable {
//...
#Override
public void run() {
while(true){
//Do what you have to do
//At the end of the iteration, get back in queue
}
}
If I use thread pools to run these, they will never left the execution, obviously.
I'd like to schedule them like in the comment I've made at the end of the iteration.
E.G.: I have 2 Runnables with infinite loops (and they have to be infinite for the task they do) and a treadpool of 1 thread (for simplicity). I want these two loops to alternate the usage of the thread. The Runnables don't know each other.
I don't know if this is even possible to be done.
Thank you for any help or suggest
EDIT: Jost solution solved the problem offering the scalability I was aiming for. Thank you.
I think you should use a ThreadPoolExecutor, remove the infinite loop and enable the two Runnables to reschedule themselves to the executor. This code snippet might help:
public class Task implements Runnable
{
private ReentrantLock lock;
private ExecutorService executor;
public Task(ExecutorService executor)
{
this.executor=executor;
}
#Override
public void run()
{
//do some stuff
//...
lock.lock();
executor.execute(this);
lock.unlock();
}
}
Note: I have not tried this example - but in general it should work. The lock ensures that the executor doesn't start with run() before it was finished (sounds a bit weird - but makes sense in the case of more than one thread in the pool).
*Jost
I can imagine something like this
final Runnable task1 = new Runnable() {
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("task1");
}
}
};
final Runnable task2 = new Runnable() {
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println("task2");
}
}
};
new Thread() {
public void run() {
for(;;) {
task1.run();
task2.run();
}
};
}.start();
The below code may achieve this but its not the best implementation
CyclicBarrier run1 = new CyclicBarrier(2);
CyclicBarrier run2 = new CyclicBarrier(2);
public class RUN1 implements Runnable {
#Override
public void run() {
while(true){
//Do what you have to do
//At the end of the iteration, get back in queue
run1.await();
run2.await();
}
}
}
public class RUN2 implements Runnable {
#Override
public void run() {
while(true){
run1.await();
//Do what you have to do
//At the end of the iteration, get back in queue
run2.await();
}
}
}
If the runnables do not knwo each other, they probably don't have to be run by the same thread. In any case, it is often better to think in terms of runnables and their possible dependencies than in threads. If there is a real reason for them to run alternating (maybe even alternating at defined switch-points, then perhaps they (or what happens inside them) should know of each other.
Normally, when running independent runnables in independent threads, the OS scheduling takes care of alternating them already. Since they are neverending, make sure you wrap the loops in try/catch(InterruptedException) blocks to be able to kill the threads nicely.
See method loopAct() in the file DataflowVariable. It is overhead for your case, but idea is simple: keep a boolean variable showing if the task is working; when the task finishes all jobs, it turns off the variable and exits; when another thread supplies a job to the task, and the variable shows it is not working, it turns on the variable and sends the task to the executor. This way you'll never get the task executed by more than one thread simultaneously.
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.
I am confused on the following:
To use threads in a Java program, the simplest way is to extend Thread class and implement the runnable interface (or simply implement runnable).
To start the thread's execution. we must call the Thread's method start(), which in turn calls method run() of the thread. And so the thread starts.
The method start() (unless I am wrong) must be called exactly and only once for each thread. As a result, thread instances can not be reused unless somehow the run method itself runs in some-short of infinite loop that facilitates a custom implementation of the thread's reusage.
Now the javadoc
link text
says
Calls to execute will reuse previously constructed threads if available
I do not understand how this is implemented.
I provide in the execute method of the executor method my custom thread e.g.
ExecutorService myCachedPool = Executors.newCachedThreadPool();
myCachedPool.execute(new Runnable(){public void run(){
//do something time consuming
}});
How can this custom thread I delegeate to the executor framework be reused?
Is Executor is allowed to call method start() more than 1 time, while we can not in our programs?
Am I misunderstanding something?
Thank you.
Note that it's not Executor that calls start() - it's ExecutorService. And no, it's not calling start() twice. It doesn't start the task that you give it directly using Thread.start()... instead, it starts a thread which knows about that thread pool's queue of work. The thread will basically wait until there's some work to do, then pick it up and execute it, before going back to waiting. So although the thread performs several tasks, Thread.start() is only called once.
EDIT: Judging by the comments, you're a bit confused about the difference between a Runnable (which is a task to be executed) and a Thread (which is what executes tasks).
The same thread can execute multiple tasks. For a very simple example not using a thread pool, consider this:
public class MultiRunnable implements Runnable
{
private final List<Runnable> runnables;
public MultiRunnable(List<Runnable> runnables)
{
this.runnables = runnables;
}
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
(Ignore the potential thread safety issues of using a List<T> from multiple threads.)
You could create a whole bunch of Runnable tasks capable of doing different things, then create a single MultiRunnable to run them in turn. Pass that instance of MultiRunnable into the Thread constructor, and then when you start the thread, it will execute each of the original runnable tasks. Does that help?
It is not calling start() more than once; instead the Thread in the pool never completes, but just stays alive---waiting. The source code is available for download if you want to look at it.
Each Thread in the thread pool can simply wait() for the Executor to hand it a new Runnable, but the Thread's own run() method has not completed. It simply waits for a new Runnable to be given to the Executor.
To "start" a thread more than once, create a runnable. For example:
//NO
private class T extends Thread { //not necessary to implement runnable
public void run(){
//...
}
}
void someMethod(){
T a = new T();
a.start();
a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
}
Instead,
//Yes
private class T implements Runnable {
public void run(){
//...
}
}
void someMethod(){
T a = new T();
new Thread(a).start();
new Thread(a).start(); //YES YES YES
}
It is also possible to do this:
void someMethod(){
final Runnable r = new Runnable(){
public void run(){
//...
}
};
new Thread(r).start();
new Thread(r).start();
}
// r could also be a field of you class.