Volatile AtomicInteger not working - java

Hi I was trying volatile. I create 10 threads from my main Thread and I print value of static counter from each thread.
The output is uncertain. Can anyone please let me know why its not working.
public class Main {
static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
while(counter.getAndIncrement() < 10){
new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(counter.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
In this I also tried changing the counter as
static volatile int counter = 0;
The out put I get is
3 3 6 6 7 7 10 10 11 11
The output is different every-time.
I don't expect them in proper order but I expect unique values from 0 - 10.

You have a single thread that's incrementing the value, and multiple threads that get and display the value. Obviously there's a lot of potential where the incrementing thread does it's thing, then the rest of the threads print the same value. Just because you call start() doesn't mean that the thread would get to run before the value has been incremented.
If instead you put just get() in the while loop, and use incrementAndGet() in the other threads, you'll get unique values (although you'll probably get more than 10).
If you want to print exactly 10 distinct values, the code is not going to work.
With the original code, you create 10 threads, but when they run, they'll print the current value of counter. If 3 of the started threads run, they'll always print the same value.
When you move the get() into the while loop, it can and will create more than 10 threads, since the other threads that increment counter won't have a chance to run yet, resulting in threads being created until 10 of the incrementing threads have run. After that there are still threads left that were created, but haven't run yet -> you get 10 + extra threads.
You can't get the output that you want with a single counter variable, if you want to use threads.

When you call
counter.getAndIncrement();
and much later in another thread call
System.out.println(counter.get());
then the values has nothing to do with one another.
If you want to retain a value, you need to do this in a variable which is not changing.
for (int i = 0; i < 10; i++) {
final threadId = i;
new Thread(new Runnable() {
#Override
public void run() {
System.out.println(threadId);
}
}).start();
}
The use of a volatile variable isn't needed but if you really want it you can do
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
#Override
public void run() {
System.out.println(counter.getAndIncrement());
}
}).start();
}

Related

Why is synchronization for count not working?

I want the final count to be 10000 always but even though I have used synchronized here, Im getting different values other than 1000. Java concurrency newbie.
public class test1 {
static int count = 0;
public static void main(String[] args) throws InterruptedException {
int numThreads = 10;
Thread[] threads = new Thread[numThreads];
for(int i=0;i<numThreads;i++){
threads[i] = new Thread(new Runnable() {
#Override
public void run() {
synchronized (this) {
for (int i = 0; i < 1000; i++) {
count++;
}
}
}
});
}
for(int i=0;i<numThreads;i++){
threads[i].start();
}
for (int i=0;i<numThreads;i++)
threads[i].join();
System.out.println(count);
}
}
Boris told you how to make your program print the right answer, but the reason why it prints the right answer is, your program effectively is single threaded.
If you implemented Boris's suggestion, then your run() method probably looks like this:
public void run() {
synchronized (test1.class) {
for (int i = 0; i < 1000; i++) {
count++;
}
}
}
No two threads can ever be synchronized on the same object at the same time, and there's only one test1.class in your program. That's good because there's also only one count. You always want the number of lock objects and their lifetimes to match the number and lifetimes of the data that they are supposed to protect.
The problem is, you have synchronized the entire body of the run() method. That means, no two threads can run() at the same time. The synchronized block ensures that they all will have to execute in sequence—just as if you had simply called them one-by-one instead of running them in separate threads.
This would be better:
public void run() {
for (int i = 0; i < 1000; i++) {
synchronized (test1.class) {
count++;
}
}
}
If each thread releases the lock after each increment operation, then that gives other threads a chance to run concurrently.
On the other hand, all that locking and unlocking is expensive. The multi-threaded version almost certainly will take a lot longer to count to 10000 than a single threaded program would do. There's not much you can do about that. Using multiple CPUs to gain speed only works when there's big computations that each CPU can do independently of the others.
For your simple example, you can use AtomicInteger instead of static int and synchronized.
final AtomicInteger count = new AtomicInteger(0);
And inside Runnable only this one row:
count.IncrementAndGet();
Using syncronized blocks the whole class to be used by another threads if you have more complex codes with many of functions to use in a multithreaded code environment.
This code does'nt runs faster because of incrementing the same counter 1 by 1 is always a single operation which cannot run more than once at a moment.
So if you want to speed up running near 10x times faster, you should counting each thread it's own counter, than summing the results in the end. You can do this with ThreadPools using executor service and Future tasks wich can return a result for you.

JAVA simple threads, magic number question (cant stop threads)

I have this assignment for android studio where I am running 2 threads, both generate random numbers and if one of the numbers is a magic number, it stops both threads and it displays the magic number on the screen. I'm not concerned about the UI elements yet, so lets not worry about that, I'm only focused on trying to stop the threads because I cant use thread.stop and to be honest this seems simple but after trying many methods I don't get how to stop the threads from running after finding a magic number, if anyone can show me how its done I would be able to understand it more. Here are the full instructions and the code:
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
/*
1. The main activity creates and starts two threads using one Runnable object. Give each thread a name when it is created.
The main activity controls the UI presentation. While waiting, it shows a ‘rotating’ progress bar.
2. Each background thread does the following:
a. sleep for 1 second,
b. generate a random four-digit number,
c. write the number and the thread’s name to the log,
d. send a message containing the number to the main thread, then repeat the cycle.
3. When the main activity receives a message containing a number, it determines if the number is ‘magic’. If it is ‘magic’,
it stops both background threads and displays the value of the magic number on the screen. (Don’t use thread.stop() to stop the threads.)
A magic number is a four digit value that either (1) is a multiple of seven or (2) is a multiple of four and ‘2’ is its last digit.
4. The first magic number written to the UI cannot be changed.
*/
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MagicNumbers();
}
private static int limit = 100000;
static int low = 1000;
static int high = 9999;
static String getThreadName;
static String currentNumber;
static Runnable create = new Runnable() {
public void run() {
for(int i = 0; i < MainActivity.limit; ++i) {
try{
Thread.sleep(1000); //makes threads sleep for 1 second
}catch(InterruptedException e) {}
getThreadName = Thread.currentThread().getName(); //gets the name of the current thread running
Random r = new Random(); //calculates random number
int result = r.nextInt(high - low) + low;
check_magic(result,getThreadName);
}
}
};
public static synchronized void check_magic(Integer value, String threadName) {
if (value % 7 == 0 || value % 4 == 0 && value % 10 == 2) {
currentNumber="MAGIC NUMBER GENERATED: "+value+", created by "+threadName;
Log.i("Program2", currentNumber);
}
else {
currentNumber="Number: "+value+", created by "+threadName;
Log.i("Program2", currentNumber);
}
}
public void MagicNumbers() {
Thread thread1 = new Thread(create);
Thread thread2 = new Thread(create);
thread1.setName("ONE");
thread2.setName("TWO");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException var7) {}
}
}
I'm only focused on trying to stop the threads because I cant use thread.stop and to be honest this seems simple but after trying many methods I don't get how to stop the threads from running after finding a magic number,
There are a number of ways that you can communicate between the threads so that they can tell each other that they have found the magic number. The easiest would be for them to both share a volatile boolean found field. So the create class would have:
private volatile boolean found;
At the loop would be:
// run until down or if the other thread finds the winning magic
for(int i = 0; i < MainActivity.limit && !found; ++i) {
The check code would look like:
if (value % 7 == 0 || value % 4 == 0 && value % 10 == 2) {
currentNumber="MAGIC NUMBER GENERATED: "+value+", created by "+threadName;
Log.i("Program2", currentNumber);
found = true;
} else {
...
}
Because the field is volatile, both threads can see the other thread's update and will stop their own loop.
Couple comments:
storing things in static fields inside of a synchronized method is not a good pattern.
Even if the one thread finds the magic, the other thread will overwrite the static fields. This might be the source of your problem. I would create a FindMagicRunnable class that implements Runnable. Both classes would need to share the same found but they should have their own currentNumber and threadName instance fields.
getThreadName is the name of a method not a field. The field is threadName.
So something like:
// both threads would set this, you could also use a shared AtomicBoolean
static volatile boolean found;
....
private static class FindMagicRunnable implements Runnable {
String threadName;
int winningMagic;
...
}
FindMagicRunnable run1 = new FindMagicRunnable();
FindMagicRunnable run2 = new FindMagicRunnable();
Thread thread1 = new Thread(run1);
Thread thread2 = new Thread(run2);
thread1.setName("ONE");
thread2.setName("TWO");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException var7) {}
if (run1.winningMagic != 0) {
// thread1 is the winner
} else {
// thread2 is the winner
}
There are some race conditions with this implementation if both threads find the winning number at the same time. If you want to get it perfect then you should use an AtomicReference and set both the name and the winning number using the testAndSet(...) atomically.

Why does this multithreaded program output 100 instead of the expected 200?

I'm learning multithreading. Can anyone tell why here the output is always 100, even though there are two threads which are doing 100 increments?
public class App {
public static int counter = 0;
public static void process() {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
Thread thread2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args) {
process();
System.out.println(counter);
}
}
The output is 100.
You're only starting the threads, not waiting for them to complete before you print the result. When I run your code, the output is 0, not 100.
You can wait for the threads with
thread1.join();
thread2.join();
(at the end of the process() method). When I add those, I get 200 as output. (Note that Thread.join() throws an InterruptedException, so you have to catch or declare this exception.)
But I'm 'lucky' to get 200 as output, since the actual behaviour is undefined as Stephen C notes. The reason why is one of the main pitfalls of multithreading: your code is not thread safe.
Basically: ++counter is shorthand for
read the value of counter
add 1
write the value of counter
If thread B does step 1 while thread A hasn't finished step 3 yet, it will try to write the same result as thread A, so you'll miss an increment.
One of the ways to solve this is using AtomicInteger, e.g.
public static AtomicInteger counter = new AtomicInteger(0);
...
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
counter.incrementAndGet();
}
}
});
Can anyone tell why here the output is always 100, even though there are two threads which are doing 100 increments?
The reason is that you have two threads writing a shared variable and a third reading, all without any synchronization. According to the Java Memory Model, this means that the actual behavior of your example is unspecified.
In reality, your main thread is (probably) printing the output before the second thread starts. (And apparently on some platforms, it prints it before the first one starts. Or maybe, it is seeing a stale value for counter. It is a bit hard to tell. But this is all within the meaning of unspecified)
Apparently, adding join calls before printing the results appears to fix the problem, but I think that is really by luck1. If you changed 100 to a large enough number, I suspect that you would find that incorrect counter values would be printed once again.
Another answer suggests using volatile. This isn't a solution. While a read operation following a write operation on a volatile is guaranteed to give the latest value written, that value may be a value written by another thread. In fact the counter++ expression is an atomic read followed by an atomic write ... but the sequence is not always atomic. If two or more threads do this simultaneously on the same variable, they are liable to lose increments.
The correct solutions to this are to either using an AtomicInteger, or to perform the counter++ operations inside a synchronized block; e.g.
for (int i = 0; i < 100; ++i) {
synchronized(App.class) {
++counter;
}
}
Then it makes no difference that the two threads may or may not be executed in parallel.
1 - What I think happens is that the first thread finishes before the second thread starts. Starting a new thread takes a significant length of time.
In Your case, There are three threads are going to execute: one main, thread1 and thread2. All these three threads are not synchronised and in this case Poor counter variable behaviour will not be specific and particular.
These kind of Problem called as Race Conditions.
Case1: If i add only one simple print statement before counter print like:
process();
System.out.println("counter value:");
System.out.println(counter);
in this situation scenario will be different. and there are lot more..
So in these type of cases, according to your requirement modification will happen.
If you want to execute one thread at time go for Thread join like:
thread1.join();
thread2.join();
join() is a Thread class method and non static method so it will always apply on thread object so apply join after thread start.
If you want to read about Multi threading in java please follow; https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032e/index.html
You are checking the result before threads are done.
thread1.start();
thread2.start();
try{
thread1.join();
thread2.join();
}
catch(InterruptedException e){}
And make counter variable volatile.

Why is this multithreaded counter producing the right result?

I'm learning multithreaded counter and I'm wondering why no matter how many times I ran the code it produces the right result.
public class MainClass {
public static void main(String[] args) {
Counter counter = new Counter();
for (int i = 0; i < 3; i++) {
CounterThread thread = new CounterThread(counter);
thread.start();
}
}
}
public class CounterThread extends Thread {
private Counter counter;
public CounterThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 10; i++) {
this.counter.add();
}
this.counter.print();
}
}
public class Counter {
private int count = 0;
public void add() {
this.count = this.count + 1;
}
public void print() {
System.out.println(this.count);
}
}
And this is the result
10
20
30
Not sure if this is just a fluke or is this expected? I thought the result is going to be
10
10
10
Try increasing the loop count from 10 to 10000 and you'll likely see some differences in the output.
The most logical explanation is that with only 10 additions, a thread is too fast to finish before the next thread gets started and adds on top of the previous result.
I'm learning multithreaded counter and I'm wondering why no matter how many times I ran the code it produces the right result.
<ttdr> Check out #manouti's answer. </ttdr>
Even though you are sharing the same Counter object, which is unsynchronized, there are a couple of things that are causing your 3 threads to run (or look like they are running) serially with data synchronization. I had to work hard on my 8 proc Intel Linux box to get it to show any interleaving.
When threads start and when they finish, there are memory barriers that are crossed. According to the Java Memory Model, the guarantee is that the thread that does the thread.join() will see the results of the thread published to it but I suspect a central memory flush happens when the thread finishes. This means that if the threads run serially (and with such a small loop it's hard for them not to) they will act as if there is no concurrency because they will see each other's changes to the Counter.
Putting a Thread.sleep(100); at the front of the thread run() method causes it to not run serially. It also hopefully causes the threads to cache the Counter and not see the results published by other threads that have already finished. Still needed help though.
Starting the threads in a loop after they all have been instantiated helps concurrency.
Another thing that causes synchronization is:
System.out.println(this.count);
System.out is a Printstream which is a synchronized class. Every time a thread calls println(...) it is publishing its results to central memory. If you instead recorded the value and then displayed it later, it might show better interleaving.
I really wonder if some Java compiler inlining of the Counter class at some point is causing part of the artificial synchronization. For example, I'm really surprised that a Thread.sleep(1000) at the front and end of the thread.run() method doesn't show 10,10,10.
It should be noted that on a non-intel architecture, with different memory and/or thread models, this might be easier to reproduce.
Oh, as commentary and apropos of nothing, typically it is recommended to implement Runnable instead of extending Thread.
So the following is my tweaks to your test program.
public class CounterThread extends Thread {
private Counter counter;
int result;
...
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt(); // good pattern
return;
}
for (int i = 0; i < 10; i++) {
counter.add();
}
result = counter.count;
// no print here
}
}
Then your main could do something like:
Counter counter = new Counter();
List<CounterThread> counterThreads = new ArrayList<>();
for (int i = 0; i < 3; i++) {
counterThread.add(new CounterThread(counter));
}
// start in a loop after constructing them all which improves the overlap chances
for (CounterThread counterThread : counterThreads) {
counterThread.start();
}
// wait for them to finish
for (CounterThread counterThread : counterThreads) {
counterThread.join();
}
// print the results
for (CounterThread counterThread : counterThreads) {
System.out.println(counterThread.result);
}
Even with this, I never see 10,10,10 output on my box and I often see 10,20,30. Closest I get is 12,12,12.
Shows you how hard it is to properly test a threaded program. Believe me, if this code was in production and you were expecting the "free" synchronization is when it would fail you. ;-)

Some problems with Threads

I'm having a-bit of trouble with threads in java. Basically Im creating an array of threads and starting them. the point of the program is to simulate a race, total the time for each competitor ( i.e. each thread ) and pick the winner.
The competitor moves one space, waits ( i.e. thread sleeps for a random period of time between 5 and 6 seconds ) and then continues. The threads don't complete in the order that they started as expected.
Now for the problem. I can get the total time it takes for a thread to complete; what I want is to store all the times from the threads into a single array and be able to calculate the fastest time.
To do this should I place the array in the main.class file? Would I be right in assuming so because if it was placed in the Thread class it wouldn't work. Or should I create a third class?
I'm alittle confused :/
It's fine to declare it in the method where you invoke the threads, with a few notes:
each thread should know its index in the array. Perhaps you should pass this in constructor
then you have three options for filling the array
the array should be final, so that it can be used within anonymous classes
the array can be passed to each thread
the threads should notify a listener when they're done, which in turn will increment an array.
consider using Java 1.5 Executors framework for submitting Runnables, rather than working directly with threads.
EDIT: The solution below assumes you need the times only after all competitors have finished the race.
You can use a structure that looks like below, (inside your main class). Typically you want to add a lot of you own stuff; this is the main outline.
Note that concurrency is not an issue at all here because you get the value from the MyRunnable instance once its thread has finished running.
Note that using a separate thread for each competitor is probably not really necessary with a modified approach, but that would be a different issue.
public static void main(String[] args) {
MyRunnable[] runnables = new MyRunnable[NUM_THREADS];
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
runnables[i] = new MyRunnable();
threads[i] = new Thread(runnables[i]);
}
// start threads
for (Thread thread : threads) {
thread.start();
}
// wait for threads
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
// ignored
}
}
// get the times you calculated for each thread
for (int i = 0; i < NUM_THREADS; i++) {
int timeSpent = runnables[i].getTimeSpent();
// do something with the time spent
}
}
static class MyRunnable implements Runnable {
private int timeSpent;
public MyRunnable(...) {
// initialize
}
public void run() {
// whatever the thread should do
// finally set the time
timeSpent = ...;
}
public int getTimeSpent() {
return timeSpent;
}
}

Categories