I have 5 threads running in an infinite loop. I need to fetch the final value after all 5 threads end every time. How can I do this?
while(true){
new Class1(1,10).start();
new Class1(11,20).start();
new Class1(21,30).start();
new Class1(31,40).start();
new Class1(41,50).start();
}
I need to determine the end of these 5 threads and pick one particular value updated in all the threads. How can I do this?
Your code here is going to start 5 new threads every single time around the loop and keep looping constantly. Are you absolutely sure that's what you want?
Just use a CountDownLatch http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
Initialize the latch at 5. Each thread counts the latch down once when it exits.
The main thread waits for the latch to hit 0 then does its processing and exits.
Do not loop creating threads!
while(true){
List<Class1> x = Arrays.asList( new Class1(1,10), new Class1(11,20), new Class1(21,30), new Class1(31,40), Class1(41,50));
for (Class1 t: x) {
x.start();
}
for (Class1 t: x) {
x.join();
}
}
Related
I'm trying to run four threads. run() method has a for loop that loops 10 times.In each loop the shared resource "x" is increment by 1. When all threads die, the for loop should have run 4x10 =40 times and x value should equal 40.
That is not happening in all runs of the my code.Each time I run the code it prints a different value of x.Most of the output values of x range from 33 to 40.
Why is it not 40 in every run? Does that mean some for loop loops are being skipped? Is it caused due being blocked?
NOTE : this does not happen when sleep() is removed. It prints 40 every single time.
My code :
public class MyThreadImplementsRunnable implements Runnable{
int x =0;
public void run() {
for(int i=0;i<10;i++){
x = x+1;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("exception");
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThreadImplementsRunnable m = new MyThreadImplementsRunnable();
Thread t1 = new Thread(m,"first");
Thread t2= new Thread(m,"second");
Thread t3= new Thread(m,"third");
Thread t4= new Thread(m,"fourth");
t1.start();
t2.start();
t3.start();
t4.start();
//To make sure not to go the next statement unless all threads die
while(t1.isAlive()|| t2.isAlive()|| t3.isAlive()||t4.isAlive()){
}
//After all threads die
System.out.println("now all threads are dead");
//value of the shared resource x after all threads exit
System.out.println(m.x);
}
}
Some test runs gave the following results :
Output:
now all threads are dead
34
Output:
now all threads are dead
33
x = x + 1 loads the value of x from memory, adds 1 to it and then stores it in x. Lets say Thread t1 loads 30 and at the same time thread t2 loads 30 they both increment 30 by 1 and store 31 in x instead of 32.
Why it's always 40 without sleep can be caused by many things I hypothesize that it's caused by each of the threads running very quickly and finishing before the next one starts.
You also don't use volatile and there are visibility issues but for now lets not get into that. This is also something you need to learn if you want to write multi-threaded code.
You are using a shared resource(x) between threads which is bound to create many problems like data race, visibility.. Your answer will be always different
#oleg I don't think Volatile will help in this scenario
I am working on a Enterprise application. I am facing some issues while running application in multithreaded environment. I am writing a program in which there is a variable whose value is getting updated(incremented) at very fast rate (for example 10000 updates/persecond). A loop runs for certain iterations and the value of the variable is incremented and stored in HashMap. Once the loop terminates and value the variable in HashMap is printed. I am getting unexpected value of the variable.
Here is demo program (Please read comments for better understanding) :
class test implements Runnable {
static ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
static AtomicInteger value_to_be_incremented_stored = new AtomicInteger(0); // variable whose value to be updated
static AtomicInteger i = new AtomicInteger(0); // this runs the loop
#Override
public void run() {
for (i.set(0); i.get() < 100000; i.incrementAndGet()) {
/*
This loop should run 100000 times and when loop terminates according to me value of variable
"value_to_be_incremented_stored" should be 100000 as its value is incremented
100000 times the loop also runs 100000 times.
*/
System.out.println("Thread > " + Thread.currentThread() + " " + value_to_be_incremented_stored.incrementAndGet());
map.put("TC", value_to_be_incremented_stored.intValue());
}
System.out.println("Output by Thread " + Thread.currentThread() + " " + map.toString());
}
public static void main(String[] args) {
test t1 = new test();
Thread thread1 = new Thread(t1);
thread1.setName("Thread 1");
Thread thread2 = new Thread(t1);
thread2.setName("Thread 2");
Thread thread3 = new Thread(t1);
thread3.setName("Thread 3");
Thread thread4 = new Thread(t1);
thread4.setName("Thread 4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
Output (it varies) :
Issue :
I am running loop for 100000 times (i.get() < 100000) then how come value of variable value_to_be_incremented_stored becomes more than 100000.
I found three defects. One there is a race condition in the for loop between the point where you compare the loop counter, and where you increment it. You should do this in one step to get an atomic operation:
for ( ; i.incrementAndGet() < 100000; ) {
The other is there is also a race condition between the increment of your counter, and placing it in the map. Even though you increment these in series, any thread could be have a different value internally (it's at a different point in the loop) and it could put a previous value in the global map. You need atomicity here to to make sure the value you increment is the value you place in the loop.
synchronized( lock ) {
value_to_be_incremented_stored.incrementAndGet();
map.put("TC", value_to_be_incremented_stored.intValue());
}
Finally for some reason the < comparison produces a value of 99999 for me. I had to use <= to fix it.
(And as we discussed in the comments, setting i.set(0) at the start of each for loop doesn't work for fairly obvious reasons. Four defects, I guess.)
class ThreadTestX implements Runnable {
static ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
static AtomicInteger value_to_be_incremented_stored = new AtomicInteger(0); // variable whose value to be updated
static AtomicInteger i = new AtomicInteger(0); // this runs the loop
static final Object lock = new Object();
#Override
public void run() {
for ( ; i.incrementAndGet() <= 100000; ) {
/*
This loop should run 100000 times and when loop terminates according to me value of variable
"value_to_be_incremented_stored" should be 100000 as its value is incremented
100000 times the loop also runs 100000 times.
*/
synchronized( lock ) {
value_to_be_incremented_stored.incrementAndGet();
// System.out.println("Thread > " + Thread.currentThread() +
// " " + value_to_be_incremented_stored.get());
map.put("TC", value_to_be_incremented_stored.intValue());
}
}
System.out.println("Output by Thread " + Thread.currentThread()
+ " " + map.toString());
}
public static void main(String[] args) {
ThreadTestX t1 = new ThreadTestX();
Thread thread1 = new Thread(t1);
thread1.setName("Thread 1");
Thread thread2 = new Thread(t1);
thread2.setName("Thread 2");
Thread thread3 = new Thread(t1);
thread3.setName("Thread 3");
Thread thread4 = new Thread(t1);
thread4.setName("Thread 4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
Output:
run:
Output by Thread Thread[Thread 4,5,main] {TC=100000}
Output by Thread Thread[Thread 3,5,main] {TC=100000}
Output by Thread Thread[Thread 1,5,main] {TC=100000}
Output by Thread Thread[Thread 2,5,main] {TC=100000}
BUILD SUCCESSFUL (total time: 0 seconds)
Afterthoughts: And in spite of getting marked correct, I'm not sure I was correct. The problem here is that you are trying to keep three things in sync: the loop counter i, the value to be incremented, and the map. Allowing any of these to be executed outside of a synchronized block may invite them to be in an unexpected state. I think the following may be safer:
#Override
public void run() {
for ( ;; ) {
synchronized( lock ) {
if( i.incrementAndGet() <= 100000 ) {
value_to_be_incremented_stored.incrementAndGet();
map.put("TC", value_to_be_incremented_stored.intValue());
}
else
break;
}
}
System.out.println("Output by Thread " + Thread.currentThread()
+ " " + map.toString());
}
This removes the need for declaring the variables as AtomicInteger, but I don't see how else you ensure that their values don't change (due to some other thread) as that loop executes.
Your "demo program" suffers from two simultaneous defects.
Defect #1 is the i.set( 0 ) pointed out by tsolakp. You say you fixed that but you are still getting a value of more than 100000. I also tried it and indeed, the final value is still larger than 100000.
I modified the program to be able to create an arbitrary number of threads, and I tried with 3, 10, and 20 threads. I got a final number of 100003, 100009, and 100019 respectively. See a pattern? So:
Defect #2 is that on the last iteration, when the value of i is 99999, the expression i.get() < 100000 is true for all threads, so all threads proceed to execute once more. The i.incrementAndGet() clause is visually sitting right next to i.get() < 1000000; but it does not get executed until the end of the loop.
So, all threads get a chance to increment i once more after the last iteration.
Everytime a new thread enters the run method it will reset your i count to zero via the first statement in the for loop by calling i.set(0).
Update: Next step after fixing reset issue, is to step through the code and see how the threads will behave.
Lets say three threads get inside the for loop while the fourth thread increments i. What will happen is that value_to_be_incremented_stored will increment 3 times and i only one time.
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.
I have the following code that runs whenever you click the Start button on my program. I have denoted via comments where I want the timer to go, problem is, when I do thread.sleep(time) it freezes my program! So, I was wondering if someoen could just simply add atimer to my code so it runs the first bit, waits, then runs it again based on bumpNum.
Code:
public class startReplyButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
int length = textAreaReplyMessage.getText().length();
int remLen = 400 - length;
String strHTML = neo.get("http://www.neopets.com/neoboards/topic.phtml?topic=" + txtTopicID.getText());
/*strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
if(strHTML.contains("No topic with ID")){
txtLog.append("Invalid Topic ID! \n");
}
else{
txtLog.append("Bumped Topic ID " + txtTopicID.getText() + "\n");
}
*/
System.out.println(strHTML);
bumpNum = 5;
wait = Integer.parseInt(textWait1.getText()) * 1000; //converting to miliseconds
int i=1;
do{
strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
txtLog.append("Board Bumped. Waiting "+ ((Integer)(wait/1000)).toString() +" Seconds..." + "\n");
//ADD TIMER HERE
i++;
}while(i <= bumpNum);
}
}
What I wish to accomplish:
User indicates how many times they want to "post"(indicated by bumpNum), the loop will first, post once:
strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
Then:
Based on users input, it will wait for however many seconds(txtWait1) and THEN repeat the posting code above until it has reached bumpNum.
And it will update txtLog with the following EACH TIME it bumps(so the program cannot be frozen):
txtLog.append("Board Bumped. Waiting "+ ((Integer)(wait/1000)).toString() +" Seconds..." + "\n");
Edit:
Sigh. Ok, now I understand. I don't know the answer. You are talking about drawing a GUI element. I suspect you want to fork a thread to do a job and then show the GUI display that you are waiting for it. You need to wait for the thread to finish (see my join code below) all of the time having the GUI element refresh UNTIL it finishes when you display some result.
This depends more on the GUI code than sleep/timer. I would start a new question now and explain !!!NOT WITH CODE!!! but with pseudo code from 1000 foot view what you want. Something like:
I am trying to fork a thread that runs in the background in [Swing/Android/etc]. I want to display to the user that the thread has been forked, I want the user interface to wait for the thread without freezing, and then I want the user interface to join with the thread and display the results.
Think about the problem like we have to think of it. Anticipate questions that we will ask. Figure out what we don't and can't know about your environment.
Best of luck.
Edit:
If you are just trying to call sleep then you don't need to fork a thread for that. All you need to do in your code is:
try {
Thread.sleep(waitingTime);
System.out.println(waitingTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
This will pause the current thread (which could be the main thread) for waitingTime milliseconds.
So you are forking 3 threads very quickly which I guess you don't want to do. If you are trying to wait for each thread to finish then you will have to do something like:
Thread thread = new Thread(new Counter(wait));
thread.start();
thread.join();
Couple of other comments:
It is considered bad form to start a thread in the constructor of a class: new Thread(this).start();
You are creating 2 thread objects inside of your Runnable. You should just create one outside of your Runnable. See above.
Thread myCounter = new Thread(this); << #1
public Counter(int waitingTime) {
new Thread(this).start(); << #2
}
I would not initialize waitingTime = 0; when defined and initialize it in the constructor. This is confusing. Remove the = 0.
int waitingTime; << remove the =0 here
public Counter(int waitingTime) {
this.waitingTime = waitingTime;
When you catch InterruptedException, be sure to handle it right. A good pattern is to reset the interrupt flag and/or quit the thread:
} catch (InterruptedException e) {
// resets the interrupt flag cleared by catching the exception
Thread.currentThread.interrupt();
// or stops the thread immediately
return;
}
You're starting a new thread each time through the loop. Rather than creating a new thread in the constructor, move the do/while loop into a normal method rather than the run method of a new thread. What you're doing is spawning a new thread that does in fact sleep, but it's not the thread that's executing the loop so that thread just continues as normal.
what is the best way to stop a thread and wait for a statement (or a method) to be executed a certain number of times by another thread?
I was thinking about something like this (let "number" be an int):
number = 5;
while (number > 0) {
synchronized(number) { number.wait(); }
}
...
synchronized(number) {
number--;
number.notify();
}
Obviously this wouldn't work, first of all because it seems you can't wait() on a int type. Furthermore, all other solutions that come to my java-naive mind are really complicated for such a simple task. Any suggestions? (Thanks!)
Sounds like you're looking for CountDownLatch.
CountDownLatch latch = new CountDownLatch(5);
...
latch.await(); // Possibly put timeout
// Other thread... in a loop
latch.countDown(); // When this has executed 5 times, first thread will unblock
A Semaphore would also work:
Semaphore semaphore = new Semaphore(0);
...
semaphore.acquire(5);
// Other thread... in a loop
semaphore.release(); // When this has executed 5 times, first thread will unblock
You might find something like a CountDownLatch useful.