I am quite new to reactive programming. I understood that it won't block the code for large data retrieval. To state that, I wrote the below code.
import reactor.core.publisher.Flux;
public class ProjectReactorExamples {
public static void main(String[] args) {
System.out.println("started " +Thread.currentThread().getName());
Flux.range(1,10).subscribe(data -> print(data));
System.out.println("Finished");
}
private static void print(long data) {
System.out.println("Printing "+data+ "with the thread "+ Thread.currentThread().getName());
}
}
In the below code I was expecting the output as
"Started"
"Finished"
"print 1 -10 " //printing 1-10
But I am always getting the output in a sequential manner which means the 'Finished ..' output is always showing after subscribe is completed. Here I can see a blocking. How do I rewrite this in order to see 'Finished' as second and subscribed data as last.
Related
I have a method that writes a file and it can be a bit slow. So I did this to avoid blocking the rest of actions:
// things A
method();
// things B
public void method(){
new Thread(() -> {
// slow stuff
}).start();
}
However it still takes a while until things B are executed after things A and I was wondering if I should do this instead:
// things A
new Thread(() -> {
method();
}).start();
// things B
public void method(){
// slow stuff
}
Or, in other words, does calling a method with a thread inside it imply waiting for the method to end, and therefore the thread?
Just to clarify things: I want to know if both options would be the same or if in the first option the thread should finish for the B instructions to start.
Does calling a method with a thread on it imply waiting for the method to end, and therefore the thread?
No. To highlight that the thread isn't a factor, I took your original code:
method();
// things B
public void method(){
new Thread(() -> {
// slow stuff
}).start();
}
And sprinkled a bunch of System.out.println() calls throughout:
one before calling method(), and one right after
one at the start of method(), and one at the end
one at the start of the thread body, and one at the end
Also:
the thread does "slow stuff" by calling Thread.sleep() for 2 seconds
each println() includes current date+time
the output is crudely formatted with indentation to show the start/end pairs of each output
import java.time.LocalDateTime;
public class ThreadExample {
public static void main(String[] args) {
System.out.println("main >> " + LocalDateTime.now());
new ThreadExample().method();
System.out.println("main << " + LocalDateTime.now());
}
public void method() {
System.out.println(" method >> " + LocalDateTime.now());
new Thread(() -> {
System.out.println(" thread >> " + LocalDateTime.now());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(" thread << " + LocalDateTime.now());
}).start();
System.out.println(" method << " + LocalDateTime.now());
}
}
Output below, which shows a few things:
the first+second output lines in main (before and after calling method()) are basically instantaneous – 09:10:22.036305 start, 09:10:22.037957 end, for a difference of 0.001652 seconds
same for method(), nearly instantaneous with start of 09:10:22.037564 and end of 09:10:22.037897, which is a difference of 0.000333 seconds
the start and finish outputs in thread are where the waiting is, starting at 09:10:22.037920, ending at 09:10:24.041840; total difference of 2.00392 seconds which is the 2 seconds we asked for with Thread.sleep() plus the tiny amount of execution time similar to the others (0.00392)
perhaps most importantly for this question, it's clear that both the original caller (in main()) and method() both finish before thread finishes ~2 seconds later
main >> 2022-06-17T09:10:22.036305
method >> 2022-06-17T09:10:22.037564
method << 2022-06-17T09:10:22.037897
thread >> 2022-06-17T09:10:22.037920
main << 2022-06-17T09:10:22.037957
thread << 2022-06-17T09:10:24.041840
I am currently working on understanding the Java concept of multithreading. I went through a tutorial which uses the Tortoise and the Hare example to explain the concept of multithreading, and to a large extent I understood the syntax and the logic of the video tutorial. At the end of the video tutorial, the Youtuber gave an assignment that involves applying Multithreading to an olympic race track.
Using my knowledege from the example, I was able to create 10 threads (representing the athletes) that run within a loop, that executes 100 times (representing 100 meters).
My challenge is that when the Thread scheduler makes an Athlete to get to 100 meters before the other 9 athletes, the remaining 9 threads always do not complete their race. This is not usually the case in a standard race track. The fact that a Thread called Usain Bolts gets to 100 first, does not mean Yohan Blake should stop running if he is at 90m at that time.
I am also interested in getting the distance (note that they are all using the same variable) for each thread, so that I can use a function to return the positions of each Thread at the end of the race.
What I have done (that did not work):
1) I have tried to use an if else construct (containing nine "else"
statement) to assign the distance of each executing thread to a new integer variable. (using the Thread.currentThread().getName() property and the name of each thread) but that did not work well for me. This was an attempt to give positions to the athletes alone using their distance but does nothing about the 9 athletes not finishing the race.
2) I have also tried to use an ArrayList to populate the distance at runtime but for some strange reasons this still overwrites the distance each time it wants to add another distance.
Below are my codes:
package olympics100meters;
import java.util.ArrayList;
public class HundredMetersTrackRules implements Runnable {
public static String winner;
public void race() {
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread ().getName ()+" is "+distance+" meters.");
boolean isRaceWon=this.isRaceWon(distance);
if (isRaceWon) {
ArrayList<Integer> numbers = new ArrayList();
numbers.add(distance);
System.out.println("testing..."+numbers);
break;
}
}
}
private boolean isRaceWon(int totalDistanceCovered) {
boolean isRaceWon=false;
if ((HundredMetersTrackRules.winner==null)&& (totalDistanceCovered==50)) {
String winnerName=Thread.currentThread().getName();
HundredMetersTrackRules.winner=winnerName;
System.out.println("The winner is "+HundredMetersTrackRules.winner);
isRaceWon=true;
}
else if (HundredMetersTrackRules.winner==null) {
isRaceWon=false;
}
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
return isRaceWon;
}
public void run() {
this.race();
}
}
This is my main method (I reduced it to 5 Athletes till I sort out the issues):
public class Olympics100Meters {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules();
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
}
}
My challenge is that ... the remaining 9 threads always do not complete their race.
This is caused by isRaceWon() method implementation. You check for it at each meter at each runner. As soon as the first runner achieves 100 meters, the break is called on next step of each runner loop (the race is won for every loop
btw, it makes sense to use volatile statuc String for winner's name, to avoid java's memory model ambiguities.
I am also interested in getting the distance ... for each thread, so that I can use a function to return the positions of each Thread at the end of the race.
If the final aim is to get the position, create a class field public List<String> finishingOrder = new ArrayList<String> and a method finish
private synchronized finish() {
finishingOrder.add(Thread.currentThread().getName())
}
and call it after the "run" loop
do not forget to call join() for all runner threads in your main. After that, the finishingOrder will contain names in order of finishing.
The code snippet below is causing isRaceWon to return true for every instance of HundredMetersTrackRules as soon as the shared winner field is set to non-null (i.e. someone wins.):
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
This in turn causes the loop in race() to break for every instance of your Runnable. The run() method exits, terminating the thread.
The issue is just a logic error and not really specific to threading. But, as other posters have mentioned, there's some threading best-practices you can also adopt in this code, such as using volatile for fields shared by threads.
Actually For Race you need to start all the Threads at once then only its Race.
CountDownLatch is better one to Implement or write Race Program.
Many other way also we can write Race program without using the CountDownLatch.
If we need to implement using base / low level then we can use volatile boolean Flag and counter variable in synchronized blocks or using wait() and notifyAll() logic, etc.,
Introduced some time delay in your program inside the for loop. Then only you can feel the Experience. Why because you are not starting all the threads at once.
Hope you are Practicing Initial / base Level so I made few changes only for better understanding and Addressed all your queries.
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
class HundredMetersTrackRules implements Runnable {
public static Main main;
HundredMetersTrackRules(Main main){
this.main=main;
}
public static String winner;
public void race() {
try{
System.out.println(Thread.currentThread().getName()+" Waiting for others...");
while(!Main.start){
Thread.sleep(3);
}
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread().getName()+" is "+distance+" meters.");
Thread.sleep(1000);
}
synchronized(main){
Main.finish--;
}
Main.places.add(Thread.currentThread().getName());
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
public void run() {
this.race();
}
}
public class Main
{
public static volatile boolean start = false;
public static int finish = 5;
final static List<String> places =
Collections.synchronizedList(new ArrayList<String>());
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules(new Main());
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
Main.start=true;
while(Main.finish!=0){
try{
Thread.sleep(100);
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
System.out.println("The winner is "+places.get(0));
System.out.println("All Places :"+places);
}
}
I've got a problem I can't really figure out. I have my main thread, and in it I want to
Send an email with an attachment
Delete the files that were attached
in that order. My problem is that I am using an email helper that I don't have control over, and it generates another thread that does the sending. Because of this, my files are being deleted before they are done being attached, and I am getting a FNF error in the mailer. I am looking to find a way to make my main thread wait until the files are done being attached. I don't know how long that will take. I don't have control over the other thread creation, so I can't use join(). Is there something I can use with Transport maybe, or a way to wait for all threads made in a method/class to stop?
The layout of my program is
//do stuff
MailHelper.sendMail(...); //thread is created somewhere in this method
deleteFiles(); //this happens before sendMail is finished!
I need to use Java 6. Worst-case I can have my main thread sleep for a few seconds, but that's unideal. Any help is appreciated
This is an interesting question! Basically you want to wait for all child threads to complete, but have no control over them.
Here is a demonstration of the technique using ThreadGroup:
Assuming you have a MailHelper class like this:
public class MailHelper {
public void sendMail(){
Thread t = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("MailHelper: Sending mail for 6s");
for(int i = 0; i < 6; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(".");
}
System.out.println("MailHelper: Sent mail!");
}
});
t.start();
}
}
then our Main class demonstrates how use it:
public class Main {
public static void main(String[] args) throws InterruptedException {
final MailHelper mh = new MailHelper();
ThreadGroup mailThreadGroup = new ThreadGroup("mailGroup");
Thread callSendmailThread = new Thread(mailThreadGroup, new Runnable() {
#Override
public void run() {
System.out.println("Calling sendMail().");
mh.sendMail();
System.out.println("sendMail() returned.");
}
});
callSendmailThread.start();
callSendmailThread.join();
System.out.println("callSendmailThread joined. Waiting for rest of ThreadGroup to finish.");
// We cannot rely on ThreadGroup.activeCount() to give us an accurate number, and it could be zero!
Thread[] mailThreads = new Thread[mailThreadGroup.activeCount() + 1];
//Therefore retry enumerate until our array was large enough to hold all
while ( mailThreadGroup.enumerate( mailThreads, true ) == mailThreads.length ) {
mailThreads = new Thread[ mailThreads.length * 2 ];
}
for(Thread t : mailThreads){
if(t != null && t.isAlive()){
System.out.println("Joining thread " + t.getName());
t.join();
System.out.println("Thread " + t.getName() + " joined.");
}
}
mailThreadGroup.destroy();
System.out.println("Done!");
}
}
The output:
Calling sendMail().
sendMail() returned.
callSendmailThread joined. Waiting for rest of ThreadGroup to finish.
Joining thread Thread-1
MailHelper: Sending mail for 6s
.
.
.
.
.
.
MailHelper: Sent mail!
Thread Thread-1 joined.
Done!
Note that you must ensure that the Thread-1 is actually started by the time you enumerate the ThreadGroup, thus joining the callSendMailThread is absolutely necessary. Otherwise you'd get a race condition.
Also note that the quirky behaviour of ThreadGroup.enumerate() must be accounted for, by retrying to enumerate all the items several times.
The easy way to solve the issue logically is to track if the mail is send sucessfully.
It can be done by any of the below
1) Set a global variable with some value after mail is send from other thread and reset it value once the attachement is deleted.
2) Instead of variable you can also try creating a file.
Thank you,
Mukeshkoshym
In this multithreading program, when I run it, I always get the output in some random order. But I was wondering if there is any way I can make this program to work in synchronized mode. Like when I runt it then for the first thread it should print out everything, then for second thread it should print out something, then for third thread it should print out everything etc etc. So sample output should be like this for each thread-
Task 1 Started
original: Hello World
Difference:- 0
Task 1 Ended
Task 2 Started
original: Hello World
Difference:- 0
Task 2 Ended
............
............
Task 15 Started
original: Hello World
Difference:- 0
Task 15 Ended
This is my below program. Any suggestions will be appreciated.
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public synchronized void run() {
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public class TestPool {
public static void main(String[] args) throws InterruptedException {
int size = 5; //Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 1; i <= 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
You commented on Jakub's answer as follows:
Can you give me example basis on my code as I just started learning about threading. It will be of great help to me.
What Jakub is saying is that forcing threads to run in a fixed sequence defeats the purpose of using threads in the first place. Think about this.
If you really do want / need your example to run the tasks in order, you may as well do this:
for (int i = 1; i <= 3 * size; i++) {
new ThreadTask(i).run();
}
i.e. just run the runnables in the current thread.
Or you could set the maximum pool size to 1, which forces the service to run the tasks in order. (Of course, this defeats the point of using threads. You won't get any parallelism this way.)
A more sensible approach would be to have each thread return its results in a Future, and then have the main thread fetch the value from each future (in the required order) and print it. Basically, you want to allow the threads to run in any order (and in parallel, if you have multiple cores), but then impose the ordering when you access the results.
The essence of thread is that they can run simultaneously, if you want them to run in order, simply do not use Thread.
There's another kind of requirement, that maybe you want several jobs to work together (simultaneously), but in a given order. In this case, I highly suggest you to implement a queuing system. That is, build a queue like
Queue <C> q
And a thread
class T implements Runnable {
public void run() {
while (!q.empty()) {
// Do something
}
}
}
You can use Runnable through ExecutorService, like the code that you've used.
You can also add some elements into the queue in "Do something" section of previous code, then you can control the order of jobs by yourself.
You can save the the reference to the previous thread and hook up the next thread to the previous one using join(). That will ensure the threads will be run in a series (next one not starting unless the previous one finished). But the point of doing that is eluding me.
public class TestPool
{
static class ThreadTask extends Thread
{
private int id;
private Thread previous;
public ThreadTask(int id, Thread previous){
this.id = id;
this.previous = previous;
}
public void run(){
if(previous != null){
try{
previous.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public static void main(String[] args) throws InterruptedException{
int size = 5; // Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
Thread previous = null;
// queue some tasks
for(int i = 1; i <= 3 * size; i++){
Thread thread = new ThreadTask(i, previous);
previous = thread;
thread.start();
//service.submit(thread);
}
// wait for termination
//service.shutdown();
//service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
Not tested, sry. I don't also know what the ExecutorService is doing, it might break this. Note that I need to be a Thread, being Runnable is not enough. Also, run() needs not be synchronised, as it will be called only once per execution. And you should not start the threads with run(), but with start().
EDIT: I just tried to run it, and the ExecutorService is fu**ing things up. If you just start the thread (like the my code does), then it's working.
I just write one producer-consumer demo in scala and java. The demo shows that the performance of Scala is so poor. Is my code wrong?
Java AVG:1933534.1171935236
Scala AVG:103943.7312328648
The Scala code:
import scala.actors.Actor.actor
import scala.actors.Actor.loop
import scala.actors.Actor.react
import scala.concurrent.ops.spawn
object EventScala {
case class Event(index: Int)
def test() {
val consumer = actor {
var count = 0l
val start = System.currentTimeMillis()
loop {
react {
case Event(c) => count += 1
case "End" =>
val end = System.currentTimeMillis()
println("Scala AVG:" + count * 1000.0 / (end - start))
exit()
}
}
}
var running = true;
for (i <- 0 to 1) {
{
spawn {
while (running) {
consumer ! Event(0)
}
consumer!"End"
}
}
}
Thread.sleep(5000)
running = false
}
def main(args: Array[String]): Unit = {
test
}
}
The Java code:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class EventJava {
static BlockingQueue<Event> queue = new LinkedBlockingQueue<EventJava.Event>();
static volatile boolean running = true;
static volatile Event sentinel = new Event(0);
static class Event {
final int index;
public Event(int index) {
this.index = index;
}
}
static class Consumer implements Runnable {
#Override
public void run() {
long count = 0;
long start = System.currentTimeMillis();
while (true) {
try {
Event event = queue.take();
if (event == sentinel) {
long end = System.currentTimeMillis();
System.out.println("Java AVG:" + count * 1000.0
/ (end - start));
break;
}
count++;
} catch (InterruptedException e) {
}
}
}
}
static class Producer implements Runnable {
#Override
public void run() {
while (running) {
queue.add(new Event(1));
}
queue.add(sentinel);
}
}
static void test() throws InterruptedException {
ExecutorService pool = Executors.newCachedThreadPool();
pool.submit(new Consumer());
pool.execute(new Producer());
pool.execute(new Producer());
Thread.sleep(5000);
running = false;
pool.shutdown();
}
public static void main(String[] args) throws InterruptedException {
test();
}
}
You are testing two very different codes. Let's consider Java, for instance:
while (true) {
Where's the opportunity for the other "actors" to take over the thread and do some processing of their own? This "actor" is pretty much hogging the thread. If you create 100000 of them, you'll see JVM get crushed under the weight of the competing "actors", or see some get all processing time while others languish.
Event event = queue.take();
if (event == sentinel) {
Why are you taking the event out of the queue without checking if it can be processed or not? If it couldn't be processed, you'll loose the event. If you added it back to the queue, it will end up after other events sent by the same source.
These are just two things that the Scala code does and the Java one doesn't.
Overall, this is a very un-scientific test. No warmup. Low number of iterations. Very very un-sciency. Look at google caliper or such for ideas on making better micro-benchmarks.
Once your numbers are clear: compile it into scala, and then decompile it into java. The answer may jump out.
I think in your case it may be the configuration of the actors. Try akka also.
I have a machine with 4 processors. If I run your java code, I get full processor usage on a single processor (25%). That is, you're using a single thread.
If I run your scala code I get full usage of all processors, I'm getting four threads.
So I suspect that two things are happening: you're getting contention updating count, and/or count isn't being incremented correctly.
Also, the test that you're doing in the loop is a pattern match in Scala, but is a simple equality in Java, but I suspect this is a minor part.
Actors are meant for small messages that result in meaningful computations, not for element-by-element data processing as above.
Your Actor code is really more comparable to an ExecutorService with multiple threads, where each message represents a new Runnable/Callable being submitted, rather than what you have in your Java code.
Your benchmark is really comparing "how fast a worker thread can consume an item from a queue" vs. "how fast can scala send a message to a mailbox, notify and schedule the actor, and handle the message". It's just not the same thing, and it's not fit for the same purpose.
Regardless, Scala can use Java threads too. Scala just gives you an additional (safer, simpler, and communications-based) concurrency mechanism.
loop and react both throw exceptions for the purpose of flow control. This means that there are two tasks given to the thread pool, only one of which does actual work. Exceptions are also much more expensive than regular returns, even when the JVM successfully optimizes them down to longjmps.