Rxjava2 blockingSubscribe vs subscribe - java

I have read the explanation about blockingSubscribe() and subscribe() but neither I can write nor find an example to see the difference of these. It seems that both of these work the same way. Could someone provide an example of these 2, preferably in Java.

blockingSubscribe blocks the current thread and processes the incomnig events on there. You can see this by running some async source:
System.out.println("Before blockingSubscribe");
System.out.println("Before Thread: " + Thread.currentThread());
Observable.interval(1, TimeUnit.SECONDS)
.take(5)
.blockingSubscribe(t -> {
System.out.println("Thread: " + Thread.currentThread());
System.out.println("Value: " + t);
});
System.out.println("After blockingSubscribe");
System.out.println("After Thread: " + Thread.currentThread());
subscribe gives no such confinement and may run on arbitrary threads:
System.out.println("Before subscribe");
System.out.println("Before Thread: " + Thread.currentThread());
Observable.timer(1, TimeUnit.SECONDS, Schedulers.io())
.concatWith(Observable.timer(1, TimeUnit.SECONDS, Schedulers.single()))
.subscribe(t -> {
System.out.println("Thread: " + Thread.currentThread());
System.out.println("Value: " + t);
});
System.out.println("After subscribe");
System.out.println("After Thread: " + Thread.currentThread());
// RxJava uses daemon threads, without this, the app would quit immediately
Thread.sleep(3000);
System.out.println("Done");

Related

Thread not awake when timed wait elapsed in java

I am study wait(long timeout) in java,and in the offcial document I found below description:
Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
Some other thread invokes the notifyAll method for this object.
Some other thread interrupts thread T.
The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.
The last item said The specified amount of real time has elapsed, more or less,so in my option if we invoke wait(time),when time elapsed,the thread should awake itself.
So I wrote below code for test.
public static void testTimedWait() {
Object lock = new Object();
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
lock.wait(5_000);
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-1").start();
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
Thread.sleep(10_000);
//lock.notifyAll();
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-2").start();
}
In Thread-1 I invoke lock.wait(5_000) and in Thread-2 I invoke Thread.sleep(10_000),so once the code start to run,Thread-1 should awake after 5 seconds and Thread-2 should awake after 10 seconds theoretically.
When we run code above,the result listed like below:
Thread-1 doesn't awake after 5 seconds!
Could someone help to understand why thread not awake when the wait time has elasped,thanks in advance!
Update1:
Change code as below:
public static void testTimedWait() {
Object lock = new Object();
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
lock.wait(20_000);
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-1").start();
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
Thread.sleep(10_000);
//lock.notifyAll();
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-2").start();
}
Above code make Thread-1 wait for 20 seconds and Thread-2 sleep for 10 seconds,Thread-1 will awake after the specific seconds.Now it works as expected.
Update2:
Remove Thread-2
public static void testTimedWait() {
Object lock = new Object();
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
lock.wait(20_000);
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-1").start();
}
The test result is also working as expected.But I still do not know why Thread-1 not awake when it wait longer then Thread-2
Your threads are both synchronized on the same object. Therefore, you have to pay attention to the methods’s effect on synchronization:
Object.wait(…):
“This method causes the current thread (referred to here as T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.”
…
“The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It competes in the usual manner with other threads for the right to synchronize on the object; once it has regained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked.”
Thread.sleep(long): “The thread does not lose ownership of any monitors.”
So, when the first thread invokes wait, it releases the lock, which is the only way how the second thread could even enter the synchronized block. Then, the second thread calls sleep, which does not release the lock. Therefore, after the time has elapsed, the first thread can not proceed, as it can’t acquire the lock, the second thread is still holding.
Of course, if you extend the first thread’s waiting time, to wait longer than the second thread, the lock has been released in the meanwhile and the first thread can proceed immediately after the waiting time.

Parallel stream doesn't look like working in parallel, completely

1. Set's parallelStream doesn't use enough thread.
Java8 parallelStream doesn't working exactly parallel.
In my computer, java8 set's parallelStream is not using enough thread when task's count is smaller than processor's count.
public class ParallelStreamSplitTest {
#Test
public void setStreamParallelTest() {
System.out.printf("Total processor count : %d \n", Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
IntStream.range(1, 8).boxed().collect(Collectors.toCollection(HashSet::new)).parallelStream().forEach((index) -> {
System.out.println("Starting " + Thread.currentThread().getName() + ", index=" + index + ", " + new Date());
try {
Thread.sleep(1000);
} catch (Exception e) {
}
});
long end = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "'s elapsed time : " + (end - start));
}
#Test
public void intStreamParallelTest() {
System.out.printf("Total processor count : %d \n", Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
IntStream.range(1, 8).parallel().forEach(index -> {
System.out.println("Starting " + Thread.currentThread().getName() + ", index=" + index + ", " + new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
});
long end = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "'s elapsed time : " + (end - start));
}
}
In my code, setStreamParallelTest takes 4 seconds whereas intStreamParallelTest takes 1 second.
I expect that setStreamParallelTest also done in 1 seconds.
Is it bug?
2. Is it okay to use parallel stream to call another api in web application? If it is wrong, why?
My web application need to call another api server in parallel. So I use parallel stream to call api.
Sets.newHashSet(api1, api2, api3, api4).parallelStream().forEach(api -> callApiSync(api))
I think all requests bound for my server share a fork-join pool. so, It looks dangerous when one of api's response is slow.
Is it correct?
The contract for parallelStream says:
Returns a possibly parallel Stream with this collection as its source. It is allowable for this method to return a sequential stream.
If you want to invoke several tasks in parallel, use an ExecutorService.

Parallel Execution: How to update Excel WorkBook using Synchronized method, only after synchronized method execution is completed?

I have written a non-static synchronized method in a class to avoid multiple threads updating the Excel Workbook at the same time. For example Thread with ID #9 and #10 are trying to update Excel, expected is that Thread#9 should complete the operation of synchronized method and then Thread#10 should be able to invoke the method which is not happening for us. Below is the code snippet.
public synchronized boolean put(String parameterName, String parameterValue) {
try {
System.out.println("Start Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
updateData(data.get("XLFileName"), data.get("XLSheetName"), parameterName, parameterValue, data.get("TestCaseID"), data.get("Iteration"));
System.out.println("End Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
return true;
} catch (FilloException flex) {
flex.printStackTrace();
// extentTest.log(LogStatus.FATAL, "A", flex.getMessage());
return false;
}
}
public void updateData(String XLFileName, String XLSheet, String parameterName, String parameterValue, String testCaseID, String iteration) throws FilloException {
Fillo fillo = new Fillo();
Connection connection = fillo.getConnection(XLFileName);
String strQuery = "Update " + XLSheet + " Set " + parameterName + "='" + parameterValue + "' where TestCaseID = '" + testCaseID + "' and Iteration = '" + iteration + "'";
connection.executeUpdate(strQuery);
connection.close();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Current Output:
Start Time:= 10 :: 2017-03-20T15:03:31.041
1 row(s) affected
Start Time:= 9 :: 2017-03-20T15:03:31.619
1 row(s) affected
End Time:= 10 :: 2017-03-20T15:03:41.201
End Time:= 9 :: 2017-03-20T15:03:41.675
Expected Output:
Start Time:= 10 :: 2017-03-20T15:03:31.041
1 row(s) affected
End Time:= 10 :: 2017-03-20T15:03:41.201
Start Time:= 9 :: 2017-03-20T15:03:31.619
1 row(s) affected
End Time:= 9 :: 2017-03-20T15:03:41.675
Tried with synchronized block as well.
Can you try with Synchronized block with lock on class as shown below.
public synchronized boolean put(String parameterName, String parameterValue) {
synchronized (DataBook.class) {
try {
System.out.println("Start Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
updateData(data.get("XLFileName"), data.get("XLSheetName"), parameterName, parameterValue, data.get("TestCaseID"), data.get("Iteration"));
System.out.println("End Time:= " + Thread.currentThread().getId() + " :: " + LocalDateTime.now().toString());
return true;
} catch (FilloException flex) {
flex.printStackTrace();
return false;
}
}
}
Since this is not static, the lock used here is an intrinsic lock, i.e. a lock per object. What it means is that you have a lock per thread, so each thread has the right to execute its own put method, thus the output you observe.
What I would suggest to obtain the desired output is to make this method static, so that the lock is associated to the class, and only one Thread will be able to access it at a time, giving you the expected output (or almost, thread 9 could start sooner than Thread 10):
public static synchronized boolean put(String parameterName, String parameterValue)

TestSubscriber does not receive OnNext when real subscriber would

In my test I have the following code:
/* two users written to realm here, verified */
TestSubscriber<RealmResults<User>> testSubscriber = new TestSubscriber<>();
usersByQuery(getRealm().where(User.class))
.filter(RealmResults::isLoaded)
.subscribe(testSubscriber);
/*
.subscribe(users1 -> {
assertTrue("Users are not two, found instead: " + users1.size(), users1.size() == 2);
Log.d("Another test", "" + users1.size() + " users on thread: " + Thread.currentThread().getName());
});
*/
try {
Log.d("Test", "Sleeping on " + Thread.currentThread().getName() + "\n");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
testSubscriber.assertValueCount(1);
The test will fail with:
java.lang.AssertionError: Number of onNext events differ; expected: 1,
actual: 0
If I replace the testSubscriber with the commented subscribe and remove the test subscriber assertion, it will pass and output:
D/Test: Sleeping on mainD/Another test: 2 users on thread: main
I do not understand why the TestSubscribers OnNext will not be called when the other one will. I'd like to use the test subscriber so I can replace the Thread.sleep block with an awaitValueCount.

Threads in Java, states? Also what is the right way to use them?

I'm up for my exame presentation the day after tomorrow, so i need to get some straight before it which i hope you guys can help me with.
First i do know that there are 4 states of Threads (i.e Running, Ready, Blocked, Terminated), however i'm not quite sure how it works in Java. In my code i use the thread.sleep(3000) to do some waiting in the program, does this make the thread Blocked or Ready?
Also it have come to my attention that i might not have used the threads the right way, let me show you some code
public class BattleHandler implements Runnable {
private Player player;
private Monster enemyMonster;
private Dungeon dungeon;
private JTextArea log;
private GameScreen gScreen;
public void run() {
try {
runBattle();
}
catch(Exception e) { System.out.println(e);}
}
public BattleHandler(Player AttackingPlayer, JTextArea log, GameScreen gScreen) {
this.player = AttackingPlayer;
this.log = log;
this.gScreen = gScreen;
}
public void setDungeon(Dungeon dungeon) {
this.dungeon = dungeon;
}
public Dungeon getDungeon() {
return dungeon;
}
public Monster getEnemyMonster() {
return enemyMonster;
}
public void setMonster() {
// First check if dungeon have been init, if not we can't generate the mob
if(dungeon != null) {
enemyMonster = new Monster();
// Generate monster stats
enemyMonster.generateStats(dungeon);
}else {
System.out.println("Dungeon was not initialized");
}
}
public void runBattle() throws InterruptedException {
// Start battle, and run until a contester is dead.
while(player.getHealth() > 0 && enemyMonster.getHealth() > 0) {
int playerStrikeDmg = player.strike();
if(enemyMonster.blockDefend()) {
log.setText( log.getText() + "\n" + player.getName() +" tried to strike " + enemyMonster.getName()+ ", but " + enemyMonster.getName() + " Blocked.");
}else if(enemyMonster.dodgeDefend()) {
log.setText( log.getText() + "\n" + player.getName() +" tried to strike " + enemyMonster.getName()+ ", but " + enemyMonster.getName() + " Blocked.");
}else {
enemyMonster.defend(playerStrikeDmg);
log.setText( log.getText() + "\n" + player.getName() +" strikes " + enemyMonster.getName()+ " for: " + playerStrikeDmg + " left: "+ enemyMonster.getHealth());
}
if(enemyMonster.getHealth() < 1) break;
Thread.sleep(3000);
// Monster Turn
int monsterDmg = enemyMonster.strike();
if(player.blockDefend()) {
log.setText( log.getText() + "\n" + enemyMonster.getName() +" tried to strike " + player.getName()+ ", but " + player.getName()+ " Blocked.");
}else if(player.dodgeDefend()) {
log.setText( log.getText() + "\n" + enemyMonster.getName() +" tried to strike " + player.getName()+ ", but " + player.getName()+ " Dodged.");
}else {
player.defend(monsterDmg);
log.setText( log.getText() + "\n" + enemyMonster.getName() +" strikes " + player.getName()+ " for: " + monsterDmg + " left: "+ player.getHealth());
}
gScreen.updateBot();
Thread.sleep(3000);
}
When i coded this i thought it was cool, but i have seen some make a class just for controlling the Thread itself. I have just made the class who uses the Sleep runable(Which is not shown in the code, but its a big class).
Would be good to get this straight, so i can point i out before they ask me about it, you know take away there ammunition. :D
Hope you guys can help me :).
Thx
Threads have more than 4 states. Also, I recommend reading Lesson: Concurrency for more information regarding threads.
Note that if you're looking to execute a task at a set interval, I highly recommend using the Executors framework.
Blocked - it will not run at all until timeout. Ready is 'runnable now but there is no processor available to run it - will run as soon as a processor becomes available'.
As all the other guys state, there are more than those, here's a simple listing:
Running - Guess what, it's running
Waiting - It waits for another thread to complete its calculation (that's the wait() method in Java). Basically such a thread can also be run by the scheduler, like the "ready" state threads.
Ready - Means that the Thread is ready for execution, once the OS-Scheduler turns to this Thread, it will execute it
Blocked - Means that there is another operation, blocking this threads execution, such as IO.
Terminated - Guess what, it's done and will be removed by the OS-Scheduler.
For a complete listing, look at the famous Wikipedia ;)
http://en.wikipedia.org/wiki/Process_state

Categories