How to use multiple thread to generate data? - java

I try to generate data set using multiple threads
I tried to create a Runnable and a couple of Threads in the following
public class DataGenerator {
static int currentRow = 0 ;
static PrintWriter pw ;
public static void main(String[] args) throws FileNotFoundException {
File file = new File("Test3.csv") ;
pw = new PrintWriter(file);
pw.println("var1,var2,var3") ;
Thread t1 = new Thread(new MyRunnable()) ;
Thread t2 = new Thread(new MyRunnable()) ;
t1.start();
t2.start();
t1.join();
t2.join();
pw.close();
System.exit(0) ;
}
}
class MyRunnable implements Runnable {
public void run () {
for ( int i = DataGenerator.currentRow; i < 50000000; DataGenerator.currentRow ++ ) {
DataGenerator.pw.println(i + ",19:05.1,some text");
System.out.println(i);
}
}
}
However is looping over o
I cant find out why

When you start a thread it leaves the thread to start up in its own thread. So what is happening is, its starting the thread and then going straight to the next call pw.close() before the thread has had a chance to start up.

Your parent thread is closing the PrintWriter pw before the child Threads t1 and t2 can use it to print. You need to have your parent thread call wait() after you've started your child Threads.
You should review the answer to How to make a Java thread wait for another thread's output? for some help. You can use this information to discover how to solve this issue from a code-standpoint; it's fairly simple.
Note: you have edited your question since this answer was posted; the answer to the following question is even more relevant: Wait until child threads completed : Java
Other useful SO questions with applicable answers that you should read:
A simple scenario using wait() and notify() in java
How to use wait and notify in Java?
Wait function in Java
Java Wait Function
Wait() / notify() synchronization
See also Java Concurrency Tutorial.

Related

Using join() method to wait for the thread execution to complete but not getting the desired result [duplicate]

This question already has answers here:
Java volatile keyword not working as expected
(6 answers)
Closed 14 days ago.
Created 2 threads and called the join() method on them. I was expecting the threads would run sequentially and give the desired result, but I am getting some random values in the result.
public class TestJoinMethod {
volatile private int count =0;
public static void main(String[] args) {
TestJoinMethod testJoinMethod = new TestJoinMethod();
testJoinMethod.execute();
}
public void execute() {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0; i<10000; i++) {
count++;
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0; i<10000; i++) {
count++;
}
}
});
t1.start();
t2.start();
try {
t1.join();
System.out.println(count);
t2.join();
System.out.println(count);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Using the above code to get the value of count variable. As per my understanding the join() method waits for the thread execution to be completed before the control of the calling thread goes to next statement. Expected result : sysout statement should print 10000 , 200000 respectively. However, the result is giving some random values : 14125 , 14125 or 16911, 16911.
Not able to understand why is this happening here, went through some tutorials also, but couldn't understand the exact issue here.
Appreciate your help here.
So let's think about the sequence that happens here. This part:
t1.start();
t2.start();
Starts the two threads running, concurrently with each other. We haven't executed a join() yet, just started the two threads, so they're both running.
try {
t1.join();
System.out.println(count);
Then we get to this join(). Both t1 and t2 have been running for a while at this point. Finally, t1 finishes and then we print out count. But t2 has also been running, so we expect count to have been incremented more than it would have been by t1 alone.
Then we get to this:
t2.join();
System.out.println(count);
This does pretty much the same thing: wait for t2 to finish, then print out count again.
It's essentially impossible to predict how much of the execution of t1 and t2 may overlap with each other though. Maybe a lot, but maybe almost none at all.
Worse, you haven't done anything to protect access to count, you're getting a data race. The result is, in a word, garbage.
To get the result you're apparently looking for, you'd have prevent concurrent access of your threads though (in other words, render the use of threads utterly useless). The obvious way to do that would be something like:
t1.start();
t1.join();
System.out.println(count);
t2.start();
t2.join();
System.out.println(count);
This should produce the result you desire--but it's equivalent to just running all the code in one thread, so there's no real point to any of it.
The compiler already is warning you that
Non-atomic operation on volatile field 'count'
The threads can randomly read the same value and update it at the same time, which will result in the same number. For example:
Thread 1 reads count = 0
Thread 2 reads count = 0
Thread 1 does 0+1
Thread 1 updates count = 1
Thread 2 does 0+1
Thread 2 updates count = 1
This can be solved synchronizing the access to the count variable, for example using AtomicInteger:
private final AtomicInteger count = new AtomicInteger(0);
count.getAndIncrement();
Also note that the final result will be 20000 for both threads, you're incrementing the same counter.

Main thread to wait two parallel threads children java

first what i am trying to do:
During the main thread execution i want to pause the main thread and start two parallel threads. As soon as both this parallel threads terminate, i'd like to start again with the main thread.
What i tried:
...
...
main thread is executing
...
...
CyclicBarrier barrier = new CyclicBarrier(2);
Thread child1 = new Thread(new ThreadBuilderTask(barrier,0));
Thread child2 = new Thread(new ThreadBuilderTask(barrier,1));
child1.start();
child2.start();
/* Now i'm expecting that child1 and child2 are running in parallel calling their fooFunction */
child1.join();
child2.join();
/*Now i'm expecting that main thread will wait for child1and also for child2 (that are running in parallel).*/
... main thread starts again after both child1 and child2 finished (reached the await of the barrier)
... (break point set here, never reached)
...
Thread builder custom class
public class ThreadBuilderTask implements Runnable{
private CyclicBarrier barrier;
private int index;
...setters and getters..
#Override
public void run() {
fooFunction(this.getIndex());
try {
this.getBarrier().await();
} catch (InterruptedException | BrokenBarrierException e) {
return;
}
}
public ThreadBuilderTask(CyclicBarrier barrier,int index){
this.barrier = barrier;
this.index = index;
}
public fooFunction(int index){
//Something taking some seconds to execute
}
It's not clear what is happening here but it is definetely not working. As soon as i call join everything stops and the main thread never restart. (I put a breakpoint after the joins to see when the main thread restarts).
Maybe there is a bit of confusion with these concepts and also i'm not sure if i need to use both the barrier and the joins or simply one of those techniques.
Thanks
Davide
As mentioned in the comments I'd also suggest to use CompletableFuture. A very basic example of your described requirements could look like this:
final Runnable runnable1 = ...;
final Runnable runnable2 = ...;
CompletableFuture<Void> future1 = CompletableFuture.runAsync(runnable1);
CompletableFuture<Void> future2 = CompletableFuture.runAsync(runnable2);
CompletableFuture.allOf(future1, future2).get(); // waits for both runnables to finish
You might want to add more/some exception handling to this example. But it should give an idea how this might work.
You may consider to use Java CompletableFuture to achieve the objective.
Using its functions like supplyAsync or runAsync you may start child threads and join their respective result in the end. Or you can simply let the main thread wait until the subsequent threads completes.
Recently I managed to implement a sample scatter-gather function using the same class.
Check Java Doc for more offerings and to find best available function: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html

Not Getting expected result in multi-threaded program

I'm not getting expected result for below program, I was expecting both producer and consumer method should execute in some sequence, but for some reason only producer method is getting executed.
I have two question here :
I'm not able to understand this behaviour.
Joining both thread together in last line of main method is working properly, I'm not able to understand difference between both.
public class ProducerConsumer {
List<Integer> data = new ArrayList<>();
synchronized void produce() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("Producing");
data.add(i);
}
wait();
}
synchronized void consume() throws InterruptedException {
System.out.println("Consuming");
data.clear();
notify();
}
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
Runnable r2 = ()-> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(r2);
thread1.start();
thread1.join();
Runnable r1 = () -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(r1);
thread.start();
thread.join();
}
Output :
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
The produce() method ends with wait(). So it blocks until some thread notifies it.
The only thread that does that is the consumer thread. But the consumer thread is started by the main method only after the producer thread has ended. And it can't end until it's been notified. So you have a deadlock.
If you join() only after the two threads are started, then the consumer thread can start without having to wait for the producer thread to be finished. That still doesn't make the program correct since
you have no guarantee that the producer thread will execute first
calling wait() at then end is useless
calling wait() out of a loop checking for a condition is incorrect
if you want methods to execute in sequence, using threads is useless. You can do everything from the main thread.
1) A notify() call does not do anything at all. Unless some other thread is already waiting to be notified.
It's up to you to guarantee that any time one of your threads calls wait(), some other thread will notify() the same object some time after the wait() has begun.
Oracle's Guarded Blocks Tutorial does a pretty good job of explaining exactly how o.wait() and o.notify() work, and it explains how to establish that guarantee.
2) There is virtually no reason to do this:
Thread t = new Thread(r);
t.start();
t.join();
Your program will use less CPU, and it will use less memory, and it will accomplish exactly the same thing if you just call r.run() instead. The entire point of threads is to allow different things to happen concurrently, and there is no concurrency if one thread joins a new thread immediately after creating it. The new Thread object is wasted unless you do something like this with it:
Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();
3) wait() and notify() are a very low-level means of communicating between threads. Your code will be easier to read and understand if you use higher-level synchronization objects that are built on top of wait() and notify() instead of directly
calling them.
A java.util.concurrent.ArrayBlockingQueue instance would be especially well suited to a "producer/consumer" application.

Is it possible to call Thread start() and join() in a single call?

I'm playing with threads in Java and i have a question about the join() method.
Let's say i have a SampleClass that extends Thread. I instantiate some new threads in the main but i want the thread's job to be completed sequentially using join().
public static void main(String[] args) {
for(int i=0; i<5; i++){
new SampleClass().start();
}
}
Is it possible to call immediately join()? ...something like this:
new SampleClass().start().join();
Or is there another approach to use? ...like this maybe:
new SampleClass().start();
try{Thread.currentThread().join();}catch(InterruptedException e){...}
Thank you very much
new SampleClass().start().join(); This is wrong.
You can achieve similar thing by
SampleClass samClass = new SampleClass();
samClass.start();
samClass.join()
The above code will have same effect as you wanted.
Now your problem is to run the Threads Sequentially. In most of these
cases you don't need threads to execute sequentially (But yes there are some scenarios).
Well If you do have to.
Then you can Do Like this
Thread t1 = ..
Thread t2 = ..
t1.start();
t1.join();
t2.start(); // t2 will start only when t1 dies
t2.join(); //
t3.start(); // t3 will start only when t2 dies..
But the above approach is not good. Because for other thread to start, previous thread
needs to die. In practice We should think of creating threads as an expensive operation
and try to reuse.
The real problem often is like this, You have to execute tasks T1 , T2 , T3 , T4
sequentially but in different Threads T1 && T3 have to run on one threads and T2 and T4
have to run on another.
So here we can use Two threads instead of 4.
Thread1 will run T1 and then Thread2 will run T2 and then Thread1 will run T3 and so on
i.e.
Thread1 -> T1
Thread2 -> T2
Thread1 -> T3
Thread2 -> T4
All task will be executed sequentially but using 2 threads only.
You can solve the problem like below
Thread1 ->run {
while(canIrun) {
executeTask(taskQueue1.next());
notifyThread2();
waitForThread2Signal();
}
}
Thread2 -.run {
while(canIrun) {
waitForThread1Signal();
executeTask(taskQueue2.next());
notifyThread1();
}
}
The wait and notify method can be implemented using CyclicBarrier very easily.
What would be the point? You can get the same effect, without the overhead, by just calling run().
You can use ExecutorService#submit(Runnable runnable).get()
Is it possible to call immediately join()?
No it is not as start() returns void . You cannot chain those methods that way. And you need to invoke join() on a Thread object.
Method start belongs to Thread class. It would be like doing this:
Thread thread = new Thread(someRunnableTask);
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object.
Thread ourOriginalThreadPointer = thread.start();
//Hence this variable references to nothing, no method can be called.
ourOriginalThreadPointer.join()
The instanciated thread doesn't need to be anonymous. You can do that:
public static void main(String[] args) {
for(int i=0; i<5; i++){
SampleClass sc = new SampleClass();
sc.start();
try {
sc.join();
} catch (InterruptedException e) {
}
}
}

synchronized thread execution

my task is to create thread in this order: if A start->start B and C, if B start->start D.
And destroy them in reverse order If D then B. If B and C then A. I hope you get it. I manage to do it but I guess there is better way to do it. Do you have any suggestions?
After your comments i have changed my code and it is much more simply. But now it looks "stupid". I would like to change hardcore of if statements and implementation, any advice? tnx for advice I'm learning with you.
This is my new code:
import java.util.*;
class RobotController implements Runnable{
String name;
public void run() {
Thread t = Thread.currentThread();
System.out.println(t.getName() + " status = " + t.isAlive());
System.out.println(t.getName() + " status = " + t.getState());
}
public static void main(String args[]) throws InterruptedException{
Thread thread_A = new Thread(new RobotController(), "Thread A");
Thread thread_B = new Thread(new RobotController(), "Thread B");
Thread thread_C = new Thread(new RobotController(), "Thread C");
Thread thread_D = new Thread(new RobotController(), "Thread D");
thread_A.start();
thread_A.join();
System.out.println(thread_A.getState());
thread_B.start();
thread_B.join();
System.out.println(thread_B.getState());
thread_C.start();
thread_C.join();
System.out.println(thread_C.getState());
thread_D.start();
System.out.println(thread_D.getState());
}
}
There are some flaws in your code which will make it not to work accordingly sometimes:
You called thread_A.start() and then checked thread_A.isAlive(). Now what if , thread_A is already completed before thread_A.isAlive() condition is checked?.thread_B and thread_C is never started. Your application fails.
Assume that thread_A is not completed and thread_A.isAlive() condition is passed, then starting of thread_B before thread_C is not always guaranteed by Java thread scheduler. Again your application fails.
Assume that thread_B starts before thread_C and if thread_B completes before thread_B.isAlive() is checked then the if condition fails and thread_D is never started. Again your application fails.
Now a point to ponder:
There is no need to check if the thread is alive after its join() method is called. It is an unnecessary runtime overhead.
EDIT
OK, Here is the modified version of code..I hope it would let you understand the dynamics of thread:
class RobotController implements Runnable
{
private final Object lock = new Object();
private void notifyThread()
{
synchronized(lock)
{
lock.notify();
}
}
public void run()
{
synchronized(lock)
{
try
{
System.out.println(Thread.currentThread().getName() + " started");
lock.wait();
System.out.println(Thread.currentThread().getName()+ " stopped");
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
public static void main(String args[]) throws InterruptedException
{
RobotController rca = new RobotController();
RobotController rcb = new RobotController();
RobotController rcc = new RobotController();
RobotController rcd = new RobotController();
Thread thread_A = new Thread(rca,"Thread A");
Thread thread_B = new Thread(rcb,"Thread B");
Thread thread_C = new Thread(rcc,"Thread C");
Thread thread_D = new Thread(rcd,"Thread D");
thread_A.start();
while (thread_A.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_B.start();
thread_C.start();
while (thread_B.getState() != Thread.State.WAITING && thread_C.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_D.start();
while (thread_D.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
rcd.notifyThread();
thread_D.join();
rcc.notifyThread();
thread_C.join();
rcb.notifyThread();
thread_B.join();
rca.notifyThread();
}
}
And here is the output:
Thread A started
Thread B started
Thread C started
Thread D started
Thread D stopped
Thread C stopped
Thread B stopped
Thread A stopped
In multi threading, there is no need of synchronization unless the common data is shared by multiple threads.
In your case, you want to start and stop the threads in a particular order. For this, there is join method in Thread class. This link shows good example of join method.
In my opinion, it is quite strange to use synchronized (lock) in your run method to lock your object. The reason is that in each Thread object has the different lock attribute, which is belong to each object. It means you are trying to lock the different objects. Actually, it doesn't make sense.
Basically, the object that you should apply the synchronized are any shared objects. For example, you need to count something and then you create a class object to share it in your class. In this case, it should be locked while being read or written.
I would like to highlight two points here:
Have a look at thread execution life cycle here. It says that, when start() method is called, thread enters in runnable state and not in running state. When thread enters in running state, that means run() method is getting exexuted. CPU/OS decides the priority of which thread should be transferred from runnable to running thread. E.g. if you call start() method for 4 threads, it is not necessary that they will execute in that particular order. (Running the same program in my pc multiple times gives me different outputs.
In your case, when the condition if(thread_A.isAlive()) is executed, it is possible that the thread A may not be in running state. Hence, the control will not go into if which is not correct.
To correct this behavior, in main, a while loop should implemented which waits until the thread becomes alive and so on.
2 . In your program, you have not assigned names to the threads and you are printing the name in the run() method. In this case, JVM assigns the names to threads in order of their execution e.g. first thread to execute will have name as 'Thread-0' and so on. Hence, we will not be able to identify which thread executed first. Assign the names using setName() method.

Categories

Resources