Facing Issues in Multithreading - java

I have written a code where it will launch the fixed number of threads from the main class. Below function is just a part of it . All threads will come to this method. I have given thread names like USER1, USER2 etc.
My requirement is that in this method after driver=WebDriver....... statement all of my threads should wait until they all get the driver. I know we can join . But unable to implement here . Can someone please guide
private void testSuitLogin(String driverType){
try{
System.out.println(Thread.currentThread().getName()+" Start Time "+System.currentTimeMillis());
driver = WebDriverFactory.getDriver(driverType);
System.out.println(Thread.currentThread().getName()+" End Time "+System.currentTimeMillis());
homePage();
googleSignIn();
driver.quit();
}
catch(Exception e){
if(driver==null)
{
totalNumberOfUsers--;
return ;
}
}
}

You can use the CountDownLatch. Create a CountDownLatch with a fixed number of thread value and call countdown() after you get the instance of the WebDriver and then call await() to wait until all the threads arrive there.
CountDownLatch countDownLatch = new CountDownLatch(fixedNumber);
private void testSuitLogin(String driverType){
try{
System.out.println(Thread.currentThread().getName()+" Start Time "+System.currentTimeMillis());
driver = WebDriverFactory.getDriver(driverType);
countDownLatch.countDown(); // decreases the value of latch by 1 in each call.
countDownLatch.await(); //It will wait until value of the latch reaches zero.
System.out.println(Thread.currentThread().getName()+" End Time "+System.currentTimeMillis());
homePage();
googleSignIn();
driver.quit();
}
catch(Exception e){
if(driver==null)
{
countDownLatch.countDown();
totalNumberOfUsers--;
return ;
}
}
}

First: If all wait for all to get the driver, then you have a problem when one fails to get the driver.
In order to have all wait for each other (I don't think I have actually ever done that, but here is a suggestion). Since you know the number of threads, you can make something like:
Thread gets driver
Thread calls a synchronized method (only 1 thread can run it at a time) that decrements a counter by 1 (initialized to the number of threads).
Thread yields.
Thread runs again, calls a method that checks if the counter has reached 0.
A: Counter is not 0 yet, thread yields.
B: Counter is 0, thread continues its work.

Related

What is the reason behind this behaviour(Thread)

I was working on Threads and decided to add some extra text before and after my focused lines of code are run, for reference. I expected to get one 'extra-text' towards the start and the other at the end. However... that's not happening and the second 'extra-text' just comes at the fourth position when I run it. I am a beginner and need to know why this is happening...
---CODE---
class Hi extends Thread{
public void run(){
for(int i=1; i<=5; i++){
System.out.println("HI!");
try{
Thread.sleep(500);
} catch(InterruptedException e){}
}
}
}
class Hey extends Thread{
public void run(){
for(int i=1; i<=5; i++){
System.out.println("HEY!");
try{
Thread.sleep(500);
} catch(InterruptedException e){}
}
}
}
public class MyClass {
public static void main(String[] args){
Hi hiObj = new Hi();
Hey heyObj = new Hey();
System.out.println("extra-text");
hiObj.start();
heyObj.start();
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("extra-text");
}
}
---OUTPUT---
extra-text
HI!
HEY!
extra-text
HEY!
HI!
HEY!
HI!
HEY!
HI!
HEY!
HI!
This is a common concurrency error.
The main method of your program runs on the main thread. Thus, before you've started the hiObj and heyObj threads, you already have one thread. After you start both of the new threads, you have three. Each executes concurrently. This means that each thread can execute code without waiting for the others. Order is not guaranteed between threads.
This causes the behavior you observe. Before hiObj or heyObj are started, the main method running on the main thread prints "extra-text". Next, hiObj and heyObj are started. The main thread reaches the line Thread.currentThead().sleep(10) which causes it to suspend execution for 10 milliseconds. On most machines (including yours), this is enough time for the other two threads to begin execution. Each thread begins the for loop in its run method and prints either "HI" or"HEY". Thus, the first three lines of output are (the order of "HI" and "HEY" are not guaranteed):
"extra-text"
"HI"
"HEY"
Next, the hiObj and heyObj threads reach the line Thread.sleep(500) which causes them to suspend execution for 500 milliseconds. After 10 milliseconds have passed, the main thread will be finished sleeping a will resume. Note that neither the hiObj or heyObj threads could have resumed by now. Thus, the next line printed will be the from the next line executed in main. This is "extra-text". Thus, the expected output is:
"extra-text"
"HI"
"HEY"
"extra-text"
Over the next few seconds, the remaining prints from the hiObj and heyObj threads will occur. In Java, the main thread exits only after all other threads have exited (unless System.exit is called or there is an uncaught exception). In this case this means the program will only exit when main reaches the end of execution and when both hiObj's and heyObj's run methods return.
To change your program so that the last "extra-text" always prints at the end, you have to cause the main thread to wait for the hiObj and heyObj threads to finish. In Java, there is a method on Thead called join which causes the calling thread to wait until the joined thread dies. In your program, you can modify MyClass to look like this:
public class MyClass {
public static void main(String[] args){
Hi hiObj = new Hi();
Hey heyObj = new Hey();
System.out.println("extra-text");
hiObj.start();
heyObj.start();
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
hiObj.join();
heyObj.join();
System.out.println("extra-text");
}
}
With this change, main will first wait for hiObj to finish and then wait for heyObj to finish before it prints "extra-text".
If you get rid of the
Thread.currentThread().sleep(10);
in the main Method you will see that your two extra texts are printed to the console immediately after execution. By using the sleep(10) you just delay the second extra text and in the meantime your 2 threads print their first output.

Multithreading start method

and this a normal thread program
class Counter implements Runnable {
private int currentValue;
public Counter() { currentValue = 0; }
public int getValue() { return currentValue; }
public void run() { // (1) Thread entry point
try {
while (currentValue < 5) {
System.out.println(Thread.currentThread().getName() + ": " + (currentValue++)); // (2) Print thread name.
Thread.sleep(250); // (3) Current thread sleeps.
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
System.out.println("Exit from thread: " + Thread.currentThread().getName());
}
}
//_______________________________________________________________________________
public class Client {
public static void main(String[] args) {
Counter counterA = new Counter(); // (4) Create a counter.
Thread worker = new Thread(counterA, "Counter A");// (5) Create a new thread.
System.out.println(worker);
worker.start(); // (6) Start the thread.
try {
int val;
do {
val = counterA.getValue(); // (7) Access the counter value.
System.out.println("Counter value read by " + Thread.currentThread().getName()+ ": " + val); // (8) Print thread name.
Thread.sleep(1000); // (9) Current thread sleeps.
} while (val < 5);
} catch (InterruptedException e) {
System.out.println("The main thread is interrupted.");
}
System.out.println("Exit from main() method.");
}
}
and the output is
Thread[Counter A,5,main]
Counter value read by main thread: 0
Counter A: 0
Counter A: 1
Counter A: 2
Counter A: 3
Counter value read by main thread: 4
Counter A: 4
Exit from thread: Counter A
Counter value read by main thread: 5
Exit from main() method.
My question is even though the worker thread was started initially before the Main thread enters it's try block, Main thread execution starts first and then when the Main thread goes to sleep child thread gets into action.
As this picture(taken from "A Programmer's Guide To Java SCJP Certification : A Comprehensive Primer 3rd Edition"
Author: Khalid A Mughal, Rolf W Rasmussen) depicts that when the start method is called on the thread it returns immediately.
Please explain this point that why on invoking start method it return immediately and does the thread get starts on calling the start method. As here on calling the start method it doesn't invoke run method of the class. So when does actually the thread starts ?
Also explain this " the call to the start() method is asynchronous."
there are three things that you are missing in your overall analysis.
Call to thread's start method is sequential not parallel. Its the call to run method of Thread that is concurrent. So if you have 5 statements in main method that call start, the 5ht is not going t be called first. Thats the 'happens before' guarantee that JVM specs give you. However the run method of 1 first may get called before or after the call to the second start statement. This depends as its more of a CPU time slicing issue rather than program execution.
When more than 1 thread runs in your program the order of output is in-deterministic. That's because they run in parallel. You can never be sure that the same program will run in same order on two machines or even in two runs on the same machine. In your question you have posted only 1 output. Run the program like 20 times one after another and match the output. I am sure 2 or 3 would be entirely different.
Finally, you are basing your analysis on the order or execution of your concurrent code. That's the biggest blooper programmer make. Concurrent programs are never intended to run in a specific order or sequence. Just try to make your Runnable work an atomic mutually exclusive task (mutually exclusive to the rest of program or even to other Runnables) and track its own execution. Dont mix Threads together.
You cannot directly enforce which Thread is executed/running when. Once you start it, it's handled on lower level(usually by OS) and the results may differ on different machine or even in different execution. If you need more control, you need to use some synchronization mechanism.
The thread is isn't started synchronously underneath the call to start(). It happens later (asynchronously). In other words, just because you called start() doesn't mean the thread has started.
They why and how are all implementation details, that may depend on JVM and/or OS implementations.

Java - Count in COUNTDOWNLATCH

While running each thread why does the countdown.getCount() always print '3' even after the previous thread has already called countdown.countDown() and reduced the Latch Count by 1?
I am kind of worndering how Java knows that the Latch Count has reached 0, so that it can release all the 3 threads.
import java.util.concurrent.CountDownLatch;
class b {
static final CountDownLatch countdown = new CountDownLatch(3);
public static void main(String[] args) {
for (int i = 0; i < 3; ++i) {
Thread t = new Thread() {
public void run() {
System.out.printf("Starting on %d other threads.\n",
countdown.getCount());
countdown.countDown();
System.out.printf("new on %d other threads.\n",
countdown.getCount());
try {
countdown.await(); // waits until everyone reaches this
// point
// System.out.println("Go again : "
// +countdown.getCount());
} catch (Exception e) {
}
}
};
t.start();
}
System.out.println("Go");
}
}
you are starting 3 threads in parallel. depending on how fast they start, they could all print "3" before any of the threads manages to call countDown() (at least for the "Starting on..." line). the "new on ..." line, however, should print out some range of numbers between 2 and 0.
It's absolutely possible that all three threads print "Starting on 3.." as the threads run in parallel, and the count doesn't change until a thread executed countDown(). To really understand what's going on, I suggest you prepend System.nanoTime() and thread name before your print statements as below:
...
Thread t = new Thread("Thread-" + i) {
...
System.out.printf("%d> %s: Starting on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
countdown.countDown();
System.out.printf("%d> %s: new on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
Sometimes you'd get an output like below which may give you the impression that Thread-2 is disregarding Thread-1's call to countDown:
1407489646569321000> Thread-0: Starting on 3 other threads.
1407489646569324000> Thread-1: Starting on 3 other threads.
1407489646602463000> Thread-1: new on 1 other threads.
1407489646569513000> Thread-2: Starting on 3 other threads.
1407489646602107000> Thread-0: new on 2 other threads.
1407489646603275000> Thread-2: new on 0 other threads.
However, that is not the case, and we can verify the correct order of operations by looking at the timestamp. The mixup in the output is due to inherent unpredictability in thread scheduling, depending on which thread gets the cpu splice.
Having said that, they may not always print 3, depending on thread scheduling or delays. As an example, try putting a Thread.sleep(..) as shown below:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 3; ++i) {
Thread t = new Thread() {
public void run() {
/* As before */
}
};
t.start();
Thread.sleep(100); // Artificial Delay
}
}
Now you should see different results like below:!
1407490223575404000> Thread-0: Starting on 3 other threads.
1407490223607879000> Thread-0: new on 2 other threads.
1407490223676233000> Thread-1: Starting on 2 other threads.
1407490223676818000> Thread-1: new on 1 other threads.
1407490223777623000> Thread-2: Starting on 1 other threads.
1407490223778221000> Thread-2: new on 0 other threads.
Internally, the CountDownLatch maintains a first in, first out wait Queue (See. AbstractQueuedSynchronizer). The value of the count is synchronized, and the waiting threads are only released when the count becomes 0 or someother thread interrupts the waiting thread. This is the mechanism used by the latch to keep track of when all the threads have arrived at the latch.
If you're interested in understanding the latch in the context of testing, checkout http://razshahriar.com/2014/08/testing-asynchronous-code-in-java-with-countdownlatch/
Hope this helps clarify your investigation of the Program behaviour.

How do I interrupt the thread and ask it to complete its work when exit has been pressed by user?

The following snippet is a thread named "Foo" that sleeps for 1 minute and then copies the data typed in 1 minute to a log file.
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
} catch(Exception exc) {
exc.printStackTrace();
}
}
I will describe one situation :
Foo thread has finished copying all the data typed in last one minute and it has been 30 seconds since it is asleep. This thread unaware of the situation that several keys are being tapped when it is asleep,will never be able to copy the key strokes into the log file when one presses System.exit(0).
Is there any way I can interrupt this thread i.e awake it and ask it to copy the data to the log file.
Please discuss how should I approach this problem.
The situation in the question :
loop started
thread is sleeping and will sleep for 1 minute
after a minute,it gets the keys tapped in the last 1 minute and copies all that
to a file
Thread sleeps again..and will sleep for 1 minute before it copies the keystrokes
It has been about 30 seconds and thread will sleep for 30 seconds more before it starts
copying the key strokes
suddenly the user presses exit button in the application
The user wants that key strokes be recorded till the second he presses exit
I cannot do System.exit(0) before checking the thread is asleep or not
How do I do this. Should I awake it or make a different call to the list and get the
key strokes because they are being recorded ? And how shall I awake it ?
You're part way there...
while(isStarted) {
try {
Thread.sleep(60000); // sleep for 1 minute
} catch(InterruptedException exc) {
exc.printStackTrace();
}
ArrayList<String> keyStrokeList = nativeMethods.getKeyStrokeList();
int result = copy.copyToLogFile(keyStrokeList);
System.out.println(result);
}
What you need to is provide a way to terminate the loop...
public void dispose() {
isStarted = false;
interrupt();
try {
join();
} catch(InterruptedException exc) {
exc.printStackTrace();
}
}
You should also know that the JVM will not exit until all non-daemon threads have completed (under normal shutdown). This means you can call System.exit(0) and the JVM will not terminate until the logger thread has terminated.
You could use this, but attaching a shut down hook which would have the capacity to call the dispose method on the logger thread...just a thought
You should use a shared object between 2 thread to implement wait/notify pattern instead of Thread.sleep(..) method.
In your condition, there are 2 threads:
Which reads buffer at 1 min interval. (Thread1)
Which will receive "exit" event first. (Thread2)
So, whenever you create instance of Thread1 you can pass a Java Object (new Object()) to it. Reader thread can be put into sleep using object.wait(60*1000); So it will sleep for max 1 minute if object.notify() is not called in 1 minute. If object.notify() is called in this duration, thread will immediately resume.
So, whenever user wants to exit from application you can call object.notify(); which will resume reader thread.
If I failed to explain you the solution due to my bad English please let me know. I will provide you a code sample.
Here's a fairly simple test case to show a way to do this:
public class InterruptTest
{
#Test
public void test() throws InterruptedException
{
//Create the logging thread and start it
LogRunnable runnable = new LogRunnable();
Thread t = new Thread(runnable);
t.start();
//Wait some time
Thread.sleep(3500);
System.out.println("User has pressed exit, starting shutdown");
//Tell the runnable to shut down
runnable.halt();
//Interrupt the thread to wake it up
t.interrupt();
//Wait until thread terminates
t.join();
System.out.println("Exiting");
}
private static class LogRunnable implements Runnable
{
private static final int SLEEPMS = 2000;
private boolean isStarted = true;
private int runCount = 1;
public void halt()
{
this.isStarted = false;
}
public void run()
{
while(isStarted)
{
try
{
Thread.sleep(SLEEPMS);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
catch(Exception exc)
{
exc.printStackTrace();
}
//Do work
System.out.println("Work done " + runCount++);
}
}
}
}
Output:
Work done 1
User has pressed exit, starting shutdown
Interrupted
Work done 2
Exiting
When the user presses the exit key, you signal your main thread to start shutting everything down (in the test-case, it simply waits for some time)
The logging thread is told to halt and awakened via a interrupt() -call
Before exiting, the main thread calls join() to wait until the logging thread has completed, you could consider using an overload that takes a timeout in case something goes wrong
The logging thread wakes up with InterruptedException, completes the code after the catches and terminates
After the logging thread has terminated, the main-thread returns from the join()-call and terminates

Java Delay/Wait

How do I delay a while loop to 1 second intervals without slowing down the entire code / computer it's running on to the one second delay (just the one little loop).
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
It seems your loop runs on Main thread and if you do sleep on that thread it will pause the app (since there is only one thread which has been paused), to overcome this you can put this code in new Thread that runs parallely
try{
Thread.sleep(1000);
}catch(InterruptedException ex){
//do stuff
}
My simple ways to delay a loop.
I already put the codes here after failing to follow the stackoverflow's standards.
//1st way: Thread.sleep : Less efficient compared to 2nd
try {
while (true) {//Or any Loops
//Do Something
Thread.sleep(sleeptime);//Sample: Thread.sleep(1000); 1 second sleep
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//================================== Thread.sleep
//2nd way: Object lock waiting = Most efficient due to Object level Sync.
Object obj = new Object();
try {
synchronized (obj) {
while (true) {//Or any Loops
//Do Something
obj.wait(sleeptime);//Sample obj.wait(1000); 1 second sleep
}
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//=============================== Object lock waiting
//3rd way: Loop waiting = less efficient but most accurate than the two.
long expectedtime = System.currentTimeMillis();
while (true) {//Or any Loops
while(System.currentTimeMillis() < expectedtime){
//Empty Loop
}
expectedtime += sleeptime;//Sample expectedtime += 1000; 1 second sleep
//Do Something
}
//===================================== Loop waiting
As Jigar has indicated you can use another Thread to do work which can operate, sleep etc independently of other Threads. The java.util.Timer class might help you as well since it can perform periodic tasks for you without you having to get into multithreaded programming.

Categories

Resources