0

This is the program

public class Thread2 implements Runnable {

    private static int runTill = 10000;
    private static int count = 0;
    @Override
    public void run() {
        for(int i=0;i<runTill;i++) {
            count++;
        }
    }
    
    public static void main(String s[]) {
        int iteration = 10;
        for(int i = 0; i < iteration ;i++) {
            Thread t = new Thread(new Thread2());
            t.start();
        }
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("Expected : "+(iteration * runTill));
        System.out.println("Actual : "+count);
    }

}

At the end I want count to be equal to (Expected : 100000). How can I achieve this?

5
  • 2
    Probably the smartest way is to use AtomicInteger.getAndIncrement(). docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/… Is there a reason why you are not using the java.util.concurrent package API? Commented Jan 29, 2021 at 15:06
  • Besides AtomicInteger, you can also consider synchronization and locks. especially if you want to manage more than just an integer (see winterbe.com/posts/2015/04/30/…) Commented Jan 29, 2021 at 15:08
  • 2
    Also, don't simply sleep to wait for the thread to complete: put the threads into a list, and use Thread.join() to wait for their completion. Commented Jan 29, 2021 at 15:15
  • 1
    Yes, I want to reinforce "don't use sleep()". Calling sleep like this to wait for threads is a terrible idea. Please call Thread.join() on each thread, or use something like a CountDownLatch Commented Jan 29, 2021 at 15:18
  • @Abra No, I think the OP is asking how to update a shared variable. His final result (100,000) is too large to be one single thread updating a instance variable 10,000 times. Commented Jan 29, 2021 at 15:35

3 Answers 3

2

A call to count++ is not atomic: it first has to load count, increment it and then store the new value in the variable. Without synchronization in place, threads will interleave during execution of this operation.

A simple way to get what you want is to use an AtomicInteger:

private static AtomicInteger count = new AtomicInteger();

@Override
public void run() {
    for(int i=0;i<runTill;i++) {
        count.incrementAndGet();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

use "compare and set" instead of "increment and get"

private static AtomicInteger count = new AtomicInteger();

@Override
public void run() {
    for(int i=0;i<runTill;i++) {

        //note: another thread might reach this point at the same time when i is 9,999
        // (especially if you have other codes running prior to the increment within the for loop)
        // then count will be added 2x if you use incrementAndGet
        boolean isSuccessful = count.compareAndSet(i, i+1);

        if(!isSuccessful) 
            System.out.println("number is not increased (another thread already updated i)");
    }
}

1 Comment

I don't think compare and set is a good match to the OP's (implied) use case. Also this is not a great way to handle an unsuccessful update.
0

As the comments suggest, besides the need for synchronizing access (to count, became an AtomicInteger here), threads should be waited to complete using Thread.join(), instead of "guessing" their runtime:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class Thread2 implements Runnable {

    private static int runTill = 10000;
    private static AtomicInteger count = new AtomicInteger();

    @Override
    public void run() {
        for (int i = 0; i < runTill; i++) {
            count.incrementAndGet();
        }
    }

    public static void main(String s[]) {
        int iteration = 10;
        List<Thread> threads = new ArrayList<Thread>();
        for (int i = 0; i < iteration; i++) {
            Thread t = new Thread(new Thread2());
            threads.add(t);
            t.start();
        }

        try {
            for (Thread t : threads)
                t.join();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }

        System.out.println("Expected : " + (iteration * runTill));
        System.out.println("Actual : " + count);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.