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.
Related
I'm trying to understand concurrent execution in Java, but given this code :
class Inter extends Thread {
public void run() {
System.out.println("Starting...");
try {
sleep(10000);
} catch (InterruptedException e) {
System.out.println("Interrupted."); }
System.out.println("Finished.");
}
public static void main(String[] args) {
Inter hi = new Inter();
hi.start();
System.out.println("Sending interruption...");
hi.interrupt();
System.out.println("Sent.");
}
}
I don't know why always give me this trace :
Sending interruption...
Sent.
Starting...
Interrupted.
Finished.
No matter how many times I run :
$ java Inter
As fars as I know in Java, when we execute the start() method in a new thread, the execution of this thread starts.
So , since the main thread and the Inter thread are concurrently executed, why can't be this a possible trace, ?
Starting..
Sending interruption..
Sent
Interrupted
Finished
So, since the main thread and the Inter thread are concurrently executed, why can't be this a possible trace?
Yes, it can. If you run your program a thousand times, most probably you will have that output at least once.
It's up to the operating system thread scheduler to arrange the threads execution in order to give that possible output, but we have no control over the scheduler. Hence, the importance of properly designing your code to prevent race conditions.
This question already has answers here:
NetworkOnMainThreadException [duplicate]
(5 answers)
Closed 5 years ago.
I created a chain of server-related operations and put them in a class called
OutgoingSync.java
I havent wrapped any threading around any of the network operations.
This is how I start the whole thing.
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(new Runnable() {
#Override
public void run() {
new OutgoingSync(context);
}
});
I am using ExecutorService because I want it to shutdown the threads for me, so I dont have to worry about that.
However, when the first network operation starts, I get a NetworkOnMainThread exception.
Here is a code snippet:
public class OutoingSync {
public OutgoingSync(Context context){
Log.e("OutgoingSync thread", Thread.currentThread.getName()); // Output "pool-2,thread-1"
doSomeStuff();
}
private void doSomeStuff() {
new UploadPhotosToServer();
}
}
public class UploadPhotosToServer {
public UploadPhotosToServer() {
Log.e("Upload photos thread", Thread.currentThread.getName()); // Output is "main"
// And the following network-related code throws a NetworkOnMainThreadException (because it is run on the main thread)
}
}
From the documentation
The exception that is thrown when an application attempts to perform a networking operation on its main thread
So, you can try running the code in AsyncTask . Its executeOnExecutor() method can do the trick.
http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)
The issue that you used submit method and not execute.
Therefore you are still on the main thread.
submit
Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return the given result upon successful completion.
execute
Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.
from [ExecuterService](http://developer.android.com/reference/java/util/concurrent/ExecutorService.html#submit(java.lang.Runnable, T))
and Executer
Currently I'm attempting to add some spacing in-between two called methods sent to the client. This can be done by issueing a Thread.sleep() command however I don't want to stop all of my logic that's going on in that thread. Instead I'm looking for a more asynchronous approach.
For example: lets say I have the following code.
void() {
foo();
then();
bar();
}
and I want them to execute in a spaced interval without effecting the main thread, like this
void() {
foo();
wait 500ms -> then();
wait 500ms -> bar();
}
I've looked into executors, but it seems they all execute on a seperate thread, then I looked into some of guavas executors, but none of them seem to be working.
You can time the execution by using a ScheduledExecutorService and its schedule() method: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html .
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(1);
scheduledExecutorService.schedule(new Runnable() {
#Override
public void run() {
// code
}
}, 500, TimeUnit.MILLISECONDS);
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!
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.