IntelliJ Thread Debug - java

Does IntelliJ IDEA provide thread-debugging? That is - Netbeans allows you to debug multiple threads, and halting at those breakpoints (automatically). However all I seem to be getting in IntelliJ is "thread dumping", which seems to be an analysis that is manual, and a snapshot taken when I clicked 'Thread Dump'.
Is there something I'm missing?
I have google'd and not found sufficient information to assist.

I think you can. I have suspended threads via breakpoints by setting the suspend policy. This will suspend the thread that is executing this piece of code. If you have multiple thread then I would think they would carry on.
To quote the suspend policy
Item Description
All : When the breakpoint is hit, all threads are suspended
Thread : When the breakpoint is hit, the thread where the breakpoint is hit is suspended.
None: No thread is suspended.

You have a nice Threads view available.
Press the little gearwheel and you will see all active threads.
And on each breakpoint you can set the Suspend Policy. You can either make the Thread alternative the default for all breakpoints or you can set them individually on each breakpoint.

For me the problem with not accessing thread still occcurs. I set up brakepoints to all. And put brakepoints inside calling methods. What I noticed is that the method in new thread is beeing accessed when i call run() but not start(). Just wondering why, AFAIK the start() method should call run(). Nevertheless, the output from thread occurs even I call .start(), but never access it.

For me the issue was that there seems to be a race condition with resuming threads after breakpoints and evaluating breakpoints in IntelliJ.
My short-term work around was to not set Breakpoints right before I spawn a thread. If I don't do this the first few Breakpoints in the run() or call() are missed.

I think the problem you have is that the child threads are being closed sooner than you expected because the main thread(the test itself) reaches to the end.
Remember that when you do a Thread.start() an asynchronous call starts, then if you are running your tests using Junit the execution will continue after this call until the end of the test, and as soon as it reaches to the end, it shutdowns the threads you started inside it.
Therefore, if you have something like:
01. import org.junit.Assert;
02. import org.junit.Test;
03. public class ThreadTest {
04. static boolean didIGetIt = false;
05. #Test
06. public void testThread() {
07. Thread myThread = new Thread(new Runnable() {
08. #Override
09. public void run() {
10. System.out.println("I am an asynchronous task");
11. System.out.println("and JUnit won't wait for me to finish my job!");
12. didIGetIt = true;
13. }
14. });
15. myThread.start();
16. Assert.assertTrue(didIGetIt);
17. }
18. }
It will execute the Assert before the code inside the run() leading to a fail test.
But if you add a simple sleep you could stop the main thread and debug and do what you need before the main thread stops.
01. import org.junit.Assert;
02. import org.junit.Test;
03. public class ThreadTest {
04. static boolean didIGetIt = false;
05. #Test
06. public void testThread() throws InterruptedException {
07. Thread myThread = new Thread(new Runnable() {
08. #Override
09. public void run() {
10. System.out.println("I am an asynchronous task");
11. System.out.println("and JUnit won't wait for me to finish my job!");
12. didIGetIt = true;
13. }
14. });
15. myThread.start();
16. System.out.println("Let's wait for child threads to finish");
17. Thread.sleep(5000);
18. Assert.assertTrue(didIGetIt);
19. }
20. }
Surely there are better ways to do it, but the Thread.sleep may be what you are looking for.
Hope it may help somebody!

Related

RxJava Schedulers.io doesn't work in maven project

I have created a maven project in Intellij IDEA , I'm trying to execute the below simple rxjava code
Observable.just(1,2,3,4)
.observeOn(Schedulers.io())
.subscribe(new Consumer<Integer>() {
#Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
I expect the result 1 , 2 , 3 , 4 to be printed in the io thread. But when I run the code, it doesn't print anything.
If I remove the observeOn(Schedulers.io) , then it prints as expected in the main thread.
I created creating a custom Thread pool as shown below
Executor executor = Executors.newFixedThreadPool(1);
Observable.just(1,2,3,4)
.observeOn(Schedulers.from(executor))
.subscribe(new Consumer<Integer>() {
#Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
This is working properly. The Schedulers.newThread() and Schedulers.computation() threads also working properly.
Only Schedulers.io has no effect in the code. Why is that?
Below is my dependency for Rxjava
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.2.4</version>
</dependency>
The RxJava Schedulers.io() schedulers use deamon threads.
A daemon thread is a thread that does not prevent the JVM from exiting
when the program finishes but the thread is still running. An example
for a daemon thread is the garbage collection.
source
In your first example, the main method finishes, and the program terminates so you don't see any output. Adding Thread.sleep() at the end of your main method will delay the exit and you should be able to see the output.
I assume Executors.newFixedThreadPool(1) doesn't use deamon threads, so it blocks the main method from exiting and you see different output.

Java Runnables start running before they are called

I have a function whose output is processed by multiple threads (created after the function call occurs). But when I run the program I receive a NullPointerException from the thread before the function is finished running. How do I specify for Java not to start the threads early?
public class MainThread extends Thread {
public MainClass() {
...
myRunnable1 = new myRunnable(args[]);
myRunnable2 = new myRunnable(args[]);
...
}
public void run() {
for (someNumberOfRuns) {
function1();
System.out.println("Done");
thread1 = new Thread(myRunnable);
thread2 = new Thread(myRunnable);
thread1.start();
thread2.start();
...
}
}
}
On the first iteration through the for loop, both thread1 and thread2 will throw NullPointException errors, then the system will print out "Done". Does anyone know why the two threads are starting before their respective start() calls in the method?
Thanks.
(Java version is 1.6u26)
Does anyone know why the two threads are starting before their respective start() calls in the method?
This does not happen under Java -- if the thread is being started then some code is starting it. I suspect that you are either calling the run() method directly in the thread that instantiates MainThread or you are calling start() in some place that you aren't expecting.
It may help if you use a debugger and put a breakpoint in the run() method to see who is calling it. If you want to use println debugging you could print out an exception that shows the stack trace inside of run():
new Throwable().printStackTrace();
If you provide the code that actually instantiates the MainThread we may be able to help you more.
If you are asking how to make a bunch of threads all wait to be started at the same time,
Have each thread execute a Runnable, and have the first line of run() be
barrier.await(LONG_TIMEOUT_MS, TimeUnit.MILLISECONDS);
where barrier is defined as
final CyclicBarrier barrier = new CyclicBarrier(numThreads + 1);
Then when you're ready for all of them to start, call
// Wait for all threads to be ready, then start them all at once
barrier.await(LONG_TIMEOUT_MS, TimeUnit.MILLISECONDS);
A timeout indicates that one of your threads did not execute withing the given time.

How to stop immediately a task which is started using an ExecutorService?

I have tried many different ways to immediately stop a task which is started using an ExecutorService, with no luck.
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call () {
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
... do many other things here..
if(Thread.currentThread.isInterrupted()) {
return null;
}
}
));
if(flag) { // may be true and directly cancel the task
future.cancel(true);
}
Sometimes I need to cancel the task immediately after it is started, you may be curious why I want to do this, well you may imagine a senario that a user accidentally hits the "Download" button to start a "Download Task" and he immediately wants to cancel the action because it was just an accidental click.
The problem is that after calling future.cancel(true), the task is not stopped and Thread.currentThread.isInterrupted() still returns false and I have no way to know the task was stopped from inside the call() method.
I am thinking of setting a flag like cancelled=true after calling future.cancel(true) and checking that flag constantly in the call() method, I think this is a hack and the code could be very ugly because the user can start many tasks at the same moment.
Is there a more elegant way of achieving what I want?
EDIT:
This really drives me mad. I have spent almost a day on this problem now. I will try to explain a little bit more for the problem I am facing.
I do the following to start 5 tasks, each task will start 5 threads to download a file. and then I stop all 5 tasks immediately. For all of the method calls below, i start a thread(ExecutorService.submit(task)) to make it asynchronous as you can tell from the suffixes of the methods.
int t1 = startTaskAysnc(task1);
int t2 = startTaskAysnc(task2);
int t3 = startTaskAysnc(task3);
int t4 = startTaskAysnc(task4);
int t5 = startTaskAysnc(task5);
int stopTaskAysnc(t1);
int stopTaskAysnc(t2);
int stopTaskAysnc(t3);
int stopTaskAysnc(t4);
int stopTaskAysnc(t5);
in startTaskAysnc(), I simply initiate a socket connection to remote server to get the size of the file(and this certainly is gonna take some time), after successfully getting the fileSize, I will start 5 threads to download different parts of the file. like the following(the code is simplified to make it more easy to follow):
public void startTaskAsync(DownloadTask task) {
Future<Void> future = executorService.submit(new Callable<Void>(
public Void call () {
// this is a synchronous call
int fileSize = getFileSize();
System.out.println(Thread.currentThread.isInterrupted());
....
Future<Void> futures = new Future<Void>[5];
for (int i = 0; i < futures.length; ++i) {
futures[i] = executorService.submit(new Callable<Void>(){...});
}
for (int i = 0; i < futures.length; ++i) {
futures[i].get(); // wait for it to complete
}
}
));
synchronized (mTaskMap) {
mTaskMap.put(task.getId(), future);
}
}
public void stopTaskAysnc(int taskId) {
executorService.execute(new Runnable(){
Future<Void> future = mTaskMap.get(taskId);
future.cancel(true);
});
}
I noticed a weird behavior that after I called stopTaskAsync() for all 5 tasks, there would always be at least one task that got stopped(i.e. Thread.currentThread.isInterrupted() return true), and the other 4 tasks kept running.
And I have tried your suggestions by setting an UncaughtExceptionHandler, but nothing comes out from that.
EDIT:
The problem was solved in this link: Can't stop a task which is started using ExecutorService
Well, the javadoc of Future.cancel(boolean) says that:
If the task has already started, then the mayInterruptIfRunning
parameter determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
so it's quite certain that the thread that executes the task is interrupted. What could have happened is that one of the
... do many other things here..
is accidentally clearing the Thread's interrupted status without performing the desired
handling. If you'll put a breakpoint in Thread.interrupt() you might catch the criminal.
Another option I can think of is that the task terminates before capturing the interrupt, either because it's completed or thrown some uncaught exception. Call Future.get() to determine that. Anyway, as asdasd mentioned, it is a good practice to set an UncaughtExceptionHandler.
What you're doing is very dangerous: you're using a thread pool to execute tasks (which I'll call downloaders), and the same thread pool to execute tasks which
wait for the downloaders to finish (which I'll call controllers)
or ask the controllers to stop
This means that if the core number of threads is reached after the controller has started, the downloaders will be put in the queue of the thread pool, and the controller thread will never finish. Similarly, if the core number of threads is reached when you execute the cancelling task, this cancelling task will be put in the queue, and won't execute until some other task is finished.
You should probably use a thread pool for downloaders, another one for controllers, and the current thread to cancel the controllers.
I think you'll find solution here. The main point is that cancel method raises InterruptedException. Please check if your thread is still running after cancellation? Are you sure that you didn't try to interrupt finished thread? Are you sure that your thread didn't fail with any other Exception? Try to set up UncaughtExceptionHandler.

interrupt() doesn't work

I am trying to terminate the thread in the following code:
public synchronized void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
this.scan();
this.distribute();
this.wait();
}
} catch (InterruptedException e) {}
}
public void cancel() {
this.interrupt();
}
But the thread won't terminate. I used the debugger and found out that after the command this.interrupt(), the thread doesn't get interrupted (I put a watch on the expression this.isInterrupted() and it stays false). Anyone has an idea why this thread won't get interrupted?
Edit:
The problem has been found. Turns out that there were two instances of this thread. I am attaching the problematic code that lead to this:
/* (class Detector extends Thread) */
Detector detector = new Detector(board);
...
Thread tdetector = new Thread(detector); /* WRONG!!! */
...
tdetector.start();
...
According to the docs, if you call interrupt() while the thread is in a wait() state, the interrupt flag will not be set. You should be getting an interrupted exception, which will exit the loop (and the thread).
EDIT
Per my comment and your response, the problem is that you have more than one of these threads running.
You are probably calling cancel on the wrong thread. If you look at it, it cancel() cancels this thread. You probably want to cancel some other thread.
It is also true that your call to isInterrupted() is unnecessary, but that won't cause interrupts to be lost ...
On the other hand, if the cancel method is a method of a class that extends Thread, then the this could be the thread that needs cancelling. (The problem for us folks trying to answer is that there is/was insufficient detail in the original question ...)

How to keep my program alive for as long a daemon thread is running?

I have a requirement, that I want to start a poller once which will run foreever until the machine is restarted or the process is being killed. Now, I tried to start the poller from a main method using a shell script, but the problem is that as soon as the main method completed its execution, the poller also stoped working, as i am not using any servers to achieve so.
I heard something about daemon threads, but I am wondering how to create a daemon thread, which will run forever, and help my poller to run also.
UPDATE:
public class SomeThread extends Thread {
#Override
public void run() {
UnitPoller unitPoller = new UnitPoller();
unitPoller.doPolling();
}
public static void main(String[] args) {
SomeThread someThread = new SomeThread();
someThread.setDaemon(true);
someThread.start();
}
}
Above is my updated class, now whenever I execute this thread from the main method, it creates a thread but as soon as the execution of main method completes, my poller stops working, as the JVM shuts down.
With this problem, what should i do.
Thanks
You just create a thread and call th.setDaemon(true) before calling th.start().
Edit:
The above answers the question "how to create a daemon thread", but (as the scope of the question has changed), a proper answer would be: don't create a daemon thread if you want your thread to keep the JVM from exiting once the main thread completed.
1) You need someThread.setDaemon(false) instead of 'true'. A daemon thread actualy does NOT stop java from shutting down.
From the javadoc:
void java.lang.Thread.setDaemon(boolean on)
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be called before the thread is started.
2) I think it's not your main, but your run() method that finishes to soon. Try to put a while (true) loop around your doPolling method.
#Override
public void run() {
UnitPoller unitPoller = new UnitPoller();
while (true)
unitPoller.doPolling();
}
3) It's cleaner to call join() inside the main then to rely on daemon thread behavior.
try {
someThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
4) If you need a clean way to shut down the deamonthread. Consider implementing InterruptedException to exit the polling task. You can also use the shutdown hook.
The term "daemon thread" in Java is a bit misleading, as it really means "that thread is not supposed to keep the JVM alive". This means that the JVM will shut down as soon as the last non-daemon thread terminated (as you already stated in your question).
What you are possibly looking for is the Apache Commons Daemon project, which allows to create nice "system services", started through /etc/init.d/ entries and all. This works on Windows and *nix systems.

Categories