Synced multithreading add 1 to number, varying results - java

I don't know if this is working the right way, but I'm attempting to add 1 to a variable using 1000 threads. I then print out the number at the end to verify that it worked, it never is 1000 and it also changes.
I determined this is likely a synchronization issue from googling and look on SO but when I try to sync the threads, it still isn't 1000 at the end and varies but a lot less (varies between 995 to 997 whereas without sync it varies between 900 and 1000 roughly).
Here is what I'm doing so far:
public class Main extends Thread{
public static void main(String[] args) {
Thread[] threads = new Thread[1000];
Adder adder = new Adder();
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new ThreadAddSync(adder));
threads[i].start();
}
System.out.println("----- " + adder.count);
}
}
public class ThreadAddSync implements Runnable{
Adder add;
public ThreadAddSync(Adder add){
this.add = add;
}
#Override
public void run() {
synchronized(add){
add.add();
}
}
}
public class Adder {
int count = 0;
public void add(){
count += 1;
}
}
My question is should these threads be synced the way I have this written? And if they are synced why are they producing varying results if they're technically safe?

System.out.println("----- " + adder.count); - you access count but don't synchronize on adder and thus, it is not safe (nor did you wait for the workers to complete, join() if you expect to see the final total before you print the total, or add another loop to wait). Also, in real code, you should be using AtomicInteger.

Related

Java concurrency using ConcurrentHashMap with synchronized block

Here is my main class that initializes and starts 5 different Threads:
public class Server implements Runnable {
Server1 server1;
Thread server1Thread;
public Server() {}
#Override
public void run() {
server1 = new Server1();
server1Thread = new Thread(server1);
server1Thread.start();
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
Server s = new Server();
s.run();
}
}
}
Here is my Server1 Runnable:
import java.util.concurrent.ConcurrentHashMap;
public class Server1 implements Runnable {
private ConcurrentHashMap<Integer, Integer> storage= new ConcurrentHashMap<>();
public Server1() {}
#Override
public void run() {
synchronized (this){
for (int i = 0; i < 10; i++) {
storage.put(i, (int)(Math.random()*100));
}
for (int i : storage.keySet()) {
System.out.print("(" + i + "," + storage.get(i) + ") ");
}
System.out.println();
}
}
}
It puts in ConcurrentHashMap storage keys from 0 to 9 and assigns them a random value between 0 and 100. After that it prints it and prints new line at the end. I have user synchronized block to make sure the thread itself access keys correctly but it prints something like this:
(0,8) (0,87) (1,60) (1,14) (2,20) (2,70) (3,5) (0,74) (0,42) (1,22) (4,96) (0,85) (1,97) (2,75) (3,68) (4,3) (5,49) (6,3) (7,9) (8,47) (9,52)
(3,2) (5,74) (2,86) (1,48) (3,5) (6,0) (4,0) (7,86) (4,22) (8,20) (2,17) (9,87)
(5,96) (5,15) (6,15) (6,92) (7,48) (8,93) (9,67)
(3,87) (7,43) (4,34) (5,48) (8,91) (9,64)
(6,84) (7,75) (8,47) (9,87)
which obviously means that some thread prints more that 10 keys that I assigned to it. How do I make every thread print exactly 10 keys and values that it is assigned to them and ensure concurrency here?
I am not sure how to test it.
Your threads don't share any internal state. They're working fine, but the output is interleaved.
For instance if you used a StringBuilder to do the I/O in one operation, you should see correct output.
StringBuilder buff = new StringBuilder();
for (int i : storage.keySet()) {
buff.append("(" + i + "," + storage.get(i) + ") ");
}
System.out.println(buff);
There is no good reason for Server to be Runnable, or even to create any instances of it.
You do not share any of the maps. If you did, then you would also want to share a common lock, but this is not the usual way to use ConcurrentMap.
All you had to do was synchronized (Server1.class) as that is common across threads. Not the instance
Here is the verified output:
(0,75) (1,9) (2,61) (3,73) (4,55) (5,34) (6,34) (7,74) (8,41) (9,0)
(0,30) (1,42) (2,46) (3,66) (4,12) (5,17) (6,62) (7,59) (8,74) (9,4)
(0,50) (1,16) (2,29) (3,74) (4,68) (5,42) (6,33) (7,91) (8,25) (9,7)
(0,49) (1,10) (2,39) (3,94) (4,12) (5,55) (6,54) (7,89) (8,21) (9,75)
(0,77) (1,10) (2,37) (3,32) (4,73) (5,39) (6,64) (7,98) (8,96) (9,44)

Sharing variable between threads in JAVA

I have two threads doing calculation on a common variable "n", one thread increase "n" each time, another decrease "n" each time, when I am not using volatile keyword on this variable, something I cannot understand happens, sb there please help explain, the snippet is like follow:
public class TwoThreads {
private static int n = 0;
private static int called = 0;
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
n = 0;
called = 0;
TwoThreads two = new TwoThreads();
Inc inc = two.new Inc();
Dec dec = two.new Dec();
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
while (called != 2) {
//System.out.println("----");
}
System.out.println(n);
}
}
private synchronized void inc() {
n++;
called++;
}
private synchronized void dec() {
n--;
called++;
}
class Inc implements Runnable {
#Override
public void run() {
inc();
}
}
class Dec implements Runnable {
#Override
public void run() {
dec();
}
}
}
1) What I am expecting is "n=0,called=2" after execution, but chances are the main thread can be blocked in the while loop;
2) But when I uncomment this line, the program when as expected:
//System.out.println("----");
3) I know I should use "volatile" on "called", but I cannot explain why the above happens;
4) "called" is "read and load" in working memory of specific thread, but why it's not "store and write" back into main thread after "long" while loop, if it's not, why a simple "print" line can make such a difference
You have synchronized writing of data (in inc and dec), but not reading of data (in main). BOTH should be synchronized to get predictable effects. Otherwise, chances are that main never "sees" the changes done by inc and dec.
You don't know where exactly called++ will be executed, your main thread will continue to born new threads which will make mutual exclusion, I mean only one thread can make called++ in each time because methods are synchronized, and you don't know each exactly thread will be it. May be two times will performed n++ or n--, you don't know this, may be ten times will performed n++ while main thread reach your condition.
and try to read about data race
while (called != 2) {
//System.out.println("----");
}
//.. place for data race, n can be changed
System.out.println(n);
You need to synchronize access to called here:
while (called != 2) {
//System.out.println("----");
}
I sugest to add getCalled method
private synchronized int getCalled() {
return called;
}
and replace called != 2 with getCalled() != 2
If you interested in why this problem occure you can read about visibility in context of java memory model.

Is this multi-threading code guaranteed to always return zero?

I am taking a book to do some mock test, I have found this question:
import java.util.concurrent.atomic.AtomicInteger;
class AtomicVariableTest {
private static AtomicInteger counter = new AtomicInteger(0);
static class Decrementer extends Thread {
public void run() {
counter.decrementAndGet(); // #1
}
}
static class Incrementer extends Thread {
public void run() {
counter.incrementAndGet(); // #2
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Incrementer().start();
new Decrementer().start();
}
System.out.println(counter);
}
}
The answer:
This program will always print 0.
But I think there is no guarantee that the threads will have completed when it prints the counter value.
I mean, most of the time it will return 0, but if you are strict with the theory there is no guarantee of this.
Am I correct?
There is guaranteed. And there is not guaranteed. There is no middle ground.
In this case there is no guarantee that the result is always zero. This is because the threads are not joined - and might never even have actually ran before the print!
For example, among other permutations, the sequence this code could have executed is:
counter.decrementAndGet(); // #1
System.out.println(counter); // Main thread
counter.incrementAndGet(); // #2
// (and so on, at some arbitrary point after the print)
Avoiding such undesired interleaving/execution is handled in Java (as per the JLS) under happens-before relationships.
If the threads were joined (to the thread with the print) then a happens-before would have been established - in this case that would mean that the threads started and finished running - and the result would be guarantee to be zero.
public static void main(String[] args) {
final List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final new Incrementer i = new Incrementer();
threads.add(i);
i.start();
final new Decrementer d = new Decrementer();
threads.add(d);
d.start();
}
for (final Thread t : threads) { t.join(); }
System.out.println(counter);
}
See one of the many duplicates: Wait until child threads completed : Java
And this is why you use the ExecutorService or ExecutorCompletionService and never deal with thread management manually because it is extremely error prone otherwise.

Adjust Fairness in Multithreading

How can I adjust fairness between given k threads to generate some output?
In other words imagine we have k threads printing "1" and n threads printing "2".
Now how can we put fairness between threads so each thread print(for example "1") as much as other (k - 1) print(for example "1").and the same for n thread printing "2".
Before you create the threads, create an array[0..numThreads-1] of empty semaphores, one for each thread you are going to create. Signal to each thread on its creation an incrementing semaphore index, 0..numThreads-1.
In the thread function, have it wait on its semaphore[index], then print something, then signal the [(index+1) mod numThreads] semaphore, then loop round to wait on the semaphore[index] again.
Once you have done that, nothing should happen at all.
Throw in one semaphore unit, anywhere.
well, I understand a little, you could make that a thread print a number if you send that number to their constructor.
for example:
public class MyThread extends Thread
{
int number = 0;
public MyThread(int number) {
this.number = number;
}
#Override
public void run()
{
while(true) {
System.out.println(this.number);
this.sleep(1000);//control exception
}
}
}
then in your main
public class Main() {
public static void main(String[] args) {
int k = 10
for(int i = 0; i < k; k++) {
MyThread mt = new MyThread(1);
mt.start();
mt.join();
}
}
}
You should repeat a similar form for Thread printing 2

cachedThreadPool not working as I expected

I'm playing around with threads and I don't understand why this isn't working as I thought.
I am trying to calculate a sum using threads and was expecting for the thread pool to wait for all tasks to finish by the time I print out the result (due to the shutdown() call and the isTerminated() check).
What am I missing here?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test5 {
private Integer sum= new Integer(0);
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
Test5 obj = new Test5();
for(int i=0; i<1000; i++){
pool.execute(obj.new Adding());
}
pool.shutdown();
while(!pool.isTerminated()) {
//could be empty loop...
System.out.println(" Is it done? : " + pool.isTerminated());
}
System.out.println(" Is it done? : " + pool.isTerminated());
System.out.println("Sum is " + obj.sum);
}
class Adding implements Runnable {
public void run() {
synchronized(this) {
int tmp = sum;
tmp+=1;
sum=new Integer(tmp);
}
}
}
}
While I do get good results, I also get output such as this:
Is it done? : true
Sum is 983
You need to sync on the main object instance. I'm using int below, Integer will work too (needs to initialized to zero explicitly).
Here is the working code
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AppThreadsSum {
int sum;
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
AppThreadsSum app = new AppThreadsSum();
for (int i = 0; i < 1000; i++) {
pool.execute(app.new Adding());
}
pool.shutdown();
while (!pool.isTerminated()) {
System.out.println(" Is it done? : " + pool.isTerminated());
}
System.out.println(" Is it done? : " + pool.isTerminated());
System.out.println("Sum is " + app.sum);
}
class Adding implements Runnable {
public void run() {
synchronized (AppThreadsSum.this) {
sum += 1;
}
}
}
}
p.s. Busy waiting is an anti-pattern to be avoided (copied from the neighbor answer to be complete and aware of this important thing, see comments)
You have a number of issues.
Your code is not threadsafe
Busy waiting is an anti-pattern to be avoided.
What do i mean by 1.?
Lets suppose we have two threads, A & B.
A reads sum into tmp as 1
B reads sum into tmp as 1
A increments sum to 2
A writes sum as 2
B increments sum to 2
B writes sum as 2
So we end up with 2 after two increments. No quite right.
Now you may say "but I have used synchronized, this should not happen". Well, you haven't.
When you create your Adding instances you new each one. You have 1000 separate Adding instances.
When you synchronized(this) you are synchronizing on the current instance, not across all Adding. So your synchronized block does nothing.
Now, the simple solution would be to use synchronized(Adding.class).
The synchronized(Adding.class) will make the code block synchronized correctly across all Adding instances.
The good solution would be to use an AtmoicInteger rather than an Integer as this increments atomically and is designed for exactly this sort of task.
Now onto 2.
You have a while(thing){} loop, this basically runs the thread like crazy testing thousands of times a millisecond until thing is true. This is a huge waste of CPU cycles. An ExecutorService has a special, blocking, method that waits until it has shutdown, awaitTermination.
Here is an example:
static final AtomicInteger sum = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
pool.execute(new Adding());
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.DAYS);
System.out.println(" Is it done? : " + pool.isTerminated());
System.out.println("Sum is " + sum);
}
static class Adding implements Runnable {
public void run() {
sum.addAndGet(1);
}
}
I would also suggest not using a cachedThreadPool in this circumstance as you have 1000 Runnables being submitted and this will generate far more Threads than you have CPUs. I would suggest using newFixedThreadPool with a sane number of Threads.
I'm not even going to go into the use of int literals and Integer and why new Integer() is not needed.

Categories