I want to write a command line daemon that runs forever. I understand that if I want the JVM to be able to shutdown gracefully in linux, one needs to wrap the bootstrap via some C code. I think I'll be ok with a shutdown hook for now.
On to my questions:
My main(String[]) block will fire off a separate Superdaemon.
The Superdaemon will poll and loop forever.
So normally I would do:
class Superdaemon extends Thread { ... }
class Bootstrap
{
public static void main( String[] args )
{
Thread t = new Superdaemon();
t.start();
t.join();
}
}
Now I figured that if I started Superdaemon via an Executor, I can do
Future<?> f = exec.submit( new Superdaemon() );
f.get();
Is Future.get() implemented with Thread.join() ?
If not, does it behave equivalently ?
Regards,
ashitaka
Yes, the way you've written these is equivalent.
However, you don't really need to wait for the Superdaemon thread to complete. When the main thread finishes executing main(), that thread exits, but the JVM will not. The JVM will keep running until the last non-daemon thread exits its run method.
For example,
public class KeepRunning {
public static void main(String[] args) {
Superdaemon d = new Superdaemon();
d.start();
System.out.println(Thread.currentThread().getName() + ": leaving main()");
}
}
class Superdaemon extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + ": starting");
try { Thread.sleep(2000); } catch(InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + ": completing");
}
}
You'll see the output:
main: leaving main()
Thread-0: starting
Thread-0: completing
In other words, the main thread finishes first, then the secondary thread completes and the JVM exits.
The issue is that books like JCIP is advocating that we use Executors to starts Threads. So I'm trying my best not to use Thread.start(). I'm not sure if I would necessarily choose a particular way of doing things just based on simplicity. There must be a more convincing reason, no ?
The convincing reason to use java.util.concurrent is that multi-threaded programming is very tricky. Java offers the tools to that (Threads, the synchronized and volatile keywords), but that does not mean that you can safely use them directly without shooting yourself in the foot: Either too much synchronization, resulting in unnecessary bottlenecks and deadlocks, or too less, resulting in erratic behaviour due to race conditions).
With java.util.concurrent you get a set of utilities (written by experts) for the most common usage patterns, that you can just use without worrying that you got the low-level stuff right.
In your particular case, though, I do not quite see why you need a separate Thread at all, you might as well use the main one:
public static void main( String[] args )
{
Runnable t = new Superdaemon();
t.run();
}
Executors are meant for tasks that you want to run in the background (when you have multiple parallel tasks or when your current thread can continue to do something else).
Future.get() will get the future response from an asynchronous call. This will also block if the call has not been completed yet. It is much like a thread join.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html
Sort'a. Future.get() is for having a thread go off and calculate something and then return it to the calling thread in a safe fashion. It'd work if the get never returned. But, I'd stick with the join call as it's simpler and no Executer overhead (not that there would be all that much).
Edit
It looks like ExecutorService.submit(Runnable) is intended to do exectly what you're attempting. It just returns null when the Runnable completes. Interesting.
Related
When I try to use methods inside a class in which I extend Thread it does not receive the methods after the run.
My class:
public class PassPhraseValidator<E> extends Thread {
private List<E> list;
private boolean isValid;
private String passPhrase;
public PassPhraseValidator(List<E> list) {
this.list = list;
}
public String getPassPhrase() {
return passPhrase;
}
public boolean isValid() {
return isValid;
}
public void run(){
this.passPhrase = Arrays.toString(list.toArray());
this.isValid = list.stream().filter(e -> Collections.frequency(list, e) > 1).count() == 0;
}
}
So when I execute this class like this:
PassPhraseValidator<Integer> validIntegerPassPhrase = new PassPhraseValidator<>(Arrays.asList(12, 18, 15, 32));
validIntegerPassPhrase.start();
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
It gives me false while it should be true because the run function wasn't ran yet.
What am I doing wrong here? How can I make multithreading part of this? It does work when I directly put it inside the methods.
The last System.out.println statement does not wait for your thread (the run function) to complete.
One way to wait for its completion is to call the join method
validIntegerPassPhrase.join(); //Need to handle the InterruptedException it might throw
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
Explanation
What you are doing is called multithreading. This allows multiple threads to execute code concurrency or in parallel. Programs run on something called the main thread. This means one thread is executing all code systematically; one instruction after another. When introducing another thread like you are, the program execution is being done on different logic at the same time. So, when you execute the start() method on your implementation of the thread class, you are causing it to execute it's respective run() method in the background until; it completes, an exception is thrown, the application is shutdown, or the thread is stopped.
Lets step through your code and analyze the scenario.
Thread object is instantiated by the main thread. Lets call this new thread thread2.
thread2 is started by the main thread.
thread2 and the main thread are both running in parallel. This means code is being executed by both of them (for simplicity) at the same time.
Two possibilities could be occurring for this issue; Java Memory Barrier (beyond the scope of this question but more reference here) or timing. The main thread is most likely reading the print statement before thread2 can finish it's respective run() method.
Solution
An approach may be not to use multi-threading at all. The creation of threads is quite a costly operation and should not be done frequently. Typically, in app's that require multi-threading thread-pools are utilized instead.
Utilize the join() blocking function. Join forces the calling thread (in this case it would be the main thread) to wait for the respective thread to finish execution before continuation.
Implement the thread with use of Promise. This object is a wrapper for the Future class, allowing for the get() method to be blocking. This means the calling thread (in this case it would be the main thread) to wait for the respective thread to finish execution before continuation. An example of Promise's can be found here.
public class YieldDemo extends Thread{
public static void main(String[] args) {
YieldDemo y1 = new YieldDemo();
YieldDemo y2= new YieldDemo();
y1.start();
y2.start();
}
public void run() {
for(int i=0;i<=5;i++) {
if(i==3) {
Thread.yield();
} else
System.out.println(i+Thread.currentThread().toString());
}
}
}
As per the documentation of yield(), thread-1 should yield and allow thread-2 to process after 3rd loop. However, the output is not as expected. Same thread continues skipping 3rd iteration. After one thread completes the loop, other thread executes with same behaviour. Please explain.
Output:
0Thread[Thread-1,5,main]
1Thread[Thread-1,5,main]
2Thread[Thread-1,5,main]
4Thread[Thread-1,5,main]
5Thread[Thread-1,5,main]
0Thread[Thread-0,5,main]
1Thread[Thread-0,5,main]
2Thread[Thread-0,5,main]
4Thread[Thread-0,5,main]
5Thread[Thread-0,5,main]
The java.lang.Thread.yield() method causes the currently executing thread object to temporarily pause and allow other threads to execute.
NOTE : That other thread can be same thread again. There is no guarantee which thread be chosen by JVM.
As with almost all aspects of Multithreading, even your case isn't guaranteed to behave as expected. Thread.yield() is just like a suggestion to the OS telling - if it is possible, then please execute other threads before this one. Depending on the architecture of your system (number of cores, and other aspects like affinity etc etc) the OS might just ignore your request.
Also, after JDK6U23, the JVM might just change your code to :
public void run() {
for(int i=0;i<=5;i++) {
// 3 is too darn small. and yield() is not necessary
// so let me just iterate 6 times now to improve performance.
System.out.println(i+Thread.currentThread().toString());
}
yield() can totally be ignored (which might be happening in your case. If you are getting the same result over and over again)
Read This article. yield method is to request for a thread to sleep. it may be happen or not.
I have a loop that doing this:
WorkTask wt = new WorkTask();
wt.count = count;
Thread a = new Thread(wt);
a.start();
When the workTask is run, the count will wt++ ,
but the WorkTask doesn't seems change the count number, and between the thread, the variable can't share within two thread, what did I wrote wrong? Thanks.
Without seeing the code for WorkThread it's hard to pin down the problem, but most likely you are missing synchronization between the two threads.
Whenever you start a thread, there are no guarantees on whether the original thread or the newly created thread runs first, or how they are scheduled. The JVM/operating system could choose to run the original thread to completion and then start running the newly created thread, run the newly created thread to completion and then switch back to the original thread, or anything in between.
In order to control how the threads run, you have to synchronize them explicitly. There are several ways to control the interaction between threads - certainly too much to describe in a single answer. I would recommend the concurrency trail of the Java tutorials for a broad overview, but in your specific case the synchronization mechanisms to get you started will probably be Thread.join and the synchronized keyword (one specific use of this keyword is described in the Java tutorials).
Make the count variable static (it looks like each thread has its own version of the variable right now) and use a mutex to make it thread safe (ie use the synchronized instruction)
From your description I came up with the following to demonstrate what I perceived as your issue. This code, should output 42. But it outputs 41.
public class Test {
static class WorkTask implements Runnable {
static int count;
#Override
public void run() {
count++;
}
}
public static void main(String... args) throws Exception {
WorkTask wt = new WorkTask();
wt.count = 41;
Thread a = new Thread(wt);
a.start();
System.out.println(wt.count);
}
}
The problem is due to the print statement running before thread had a chance to start.
To cause the current thread ( the thread that is going to read variable count ) to wait until the thread finishes, add the following after starting thre thread.
a.join();
If you are wishing to get a result back from a thread, I would recommend you to use Callable
interface and an ExecutorSercive to submit it. e.g:
Future future = Executors.newCachedThreadPool().submit
(new Callable<Interger>()
{
int count = 1000;
#Override public Integer call() throws Exception
{
//here goes the operations you want to be executed concurrently.
return count + 1; //Or whatever the result is.
}
}
//Here goes the operations you need before the other thread is done.
System.out.println(future.get()); //Here you will retrieve the result from
//the other thread. if the result is not ready yet, the main thread
//(current thread) will wait for it to finish.
this way you don't have to deal with the synchronization problems and etc.
you can see further about this in Java documentations:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
I wrote a test app that should never stop. It issues t.wait() (t is a Thread object), but I never call notify. Why does this code end?
Despite the main thread synchronizing on t, the spawned thread runs, so it doesn't lock this object.
public class ThreadWait {
public static void main(String sArgs[]) throws InterruptedException {
System.out.println("hello");
Thread t = new MyThread();
synchronized (t) {
t.start();
Thread.sleep(5000);
t.wait();
java.lang.System.out.println("main done");
}
}
}
class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
java.lang.System.out.println("" + i);
try {
Thread.sleep(500);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
The result is that the main thread waits 5 seconds and during this time worker gives its output. Then after 5 seconds are finished, the program exits. t.wait() does not wait. If the main thread wouldn't sleep for 5 seconds (commenting this line), then t.wait() would actually wait until the worker finishes. Of course, join() is a method to use here, but, unexpectedly, wait() does the same thing as join(). Why?
Maybe the JVM sees that, since only one thread is running, there is no chance to notify the main thread and solves the deadlock. If this is true, is it a documented feature?
I'm testing on Windows XP, Java 6.
You're waiting on a Thread - and while most objects aren't implicitly notified, a Thread object is notified when the thread terminates. It's documented somewhere (I'm looking for it...) that you should not use wait/notify on Thread objects, as that's done internally.
This is a good example of why it's best practice to use a "private" object for synchronization (and wait/notify) - something which only your code knows about. I usually use something like:
private final Object lock = new Object();
(In general, however, it's cleaner to use some of the higher-level abstractions provided by java.util.concurrent if you can. As noted in comments, it's also a good idea to implement Runnable rather than extending Thread yourself.)
The JavaDoc for wait gives the answer: spurious wakeups are possible. This means the JVM is free to end a call to wait whenever it wants.
The documentation even gives you a solution if you don't want this (which is probably always the case): put the call to wait in a loop and check whether the condition you wait for has become true after every wakeup.
I got a question about interrupting threads in Java. Say I have a Runnable:
public MyRunnable implements Runnable {
public void run() {
operationOne();
operationTwo();
operationThree();
}
}
I want to implement something like this:
Thread t = new Thread(new MyRunnable());
t.run();
... // something happens
// we now want to stop Thread t
t.interrupt(); // MyRunnable receives an InterruptedException, right?
... // t is has now been terminated.
How can I implement this in Java? Specifically, how do I catch the InterruptedException in MyRunnable?
I recommend testing for Thread.isInterrupted(). Javadoc here. The idea here is that you are doing some work, most likely in a loop. On every iteration you should check if the interrupted flag is true and stop the work.
while(doingWork && !Thread.isInterrupted() {
// do the work
}
Edit: To be clear, your thread won't receive an InterruptedException if the sub tasks are not blocking or worst, eat that exception. Checking for the flag is the right method but not everybody follows it.
First, the 2nd line of your 2nd block of code should be t.start(), not t.run(). t.run() simply calls your run method in-line.
And yes, MyRunnable.run() must check periodically, while it is running, for Thread.currentThread().isInterrupted(). Since many things you might want to do in a Runnable involve InterruptedExceptions, my advice is to bite the bullet and live with them. Periodically call a utility function
public static void checkForInterrupt() throws InterruptedException {
if (Thread.currentThread().isInterrupted())
throw new InterruptedException();
}
EDIT added
Since I see a comment that the poster has no control over the individual operations, his MyRunnable.run() code should look like
public void run() {
operation1();
checkForInterrupt();
operation2();
checkForInterrupt();
operation3();
}
an InterruptedThreadException is only thrown when the thread is being blocked (wait, sleep, etc.) . Otherwise, you'll have to check Thread.currentThread().isInterrupted().
I think the answers above will pretty much fit your problem. I just want to add something on InterruptedException
Javadoc says:
InterruptedException :Thrown when a thread is waiting, sleeping, or
otherwise paused for a long time and another thread interrupts it
using the interrupt method in class Thread.
This means InterruptedException won't be thrown while running
operationOne();
operationTwo();
operationThree();
unless you are either sleeping, waiting for a lock or paused somewhere in these three methods.
EDIT If the provided code can not be changed as suggested by the nice and useful answers around here then I am afraid you have no way of interrupting your thread. As apposed to other languages such as C# where a thread can be aborted by calling Thread.Abort() Java does not have that possibility. See this link to know more about the exact reasons.
First of all, should be class in there
public class MyRunnable extends Thread {
public void run() {
if(!isInterrupted()){
operationOne();
operationTwo();
operationThree();
}
}
}
Would this work better?