0

I am writing code to let 4 threads build a histogram.

I have an array in main:

int N = 10000;
Random r = new Random();
int[] a = new int[N];

for (int i = 0; i < a.length; i++)
{
    a[i] = Math.abs(r.nextInt() % 100);
}

So basically what I want to do is cycle through this array and count how many times each number appears.

So I have written my thread class, and I used AtomicInteger which I thought would help solve the problem of multiple threads trying to access the same index simultaneously.

import java.util.concurrent.atomic.AtomicInteger;

public class UseThread implements Runnable
{
private static int[] array;
private static AtomicInteger[] count;
private static boolean[] check;

public UseThread(int[] array, AtomicInteger[] count)
{
    this.array = array;
    this.count = count;
    this.check = new boolean[array.length];
}

public void run()
{
    for (int i = 0; i < array.length; i++)
    {
        if (!getIndex(this.check[i]))
        {
            this.check[i] = true;
            int number = array[i];
            count[number].incrementAndGet();
        }
    }
}

public synchronized static boolean getIndex(boolean check2)
{
    return check2;
}

However, this hasn't quite fixed my problem. Some of the threads are accessing the array at the same time, making the count array, hold a larger value than the length of the array array.

I think the problem is in the boolean array of checking. I have a feeling that multiple threads access the same boolean array index at the same time.

I figure it is probably a simple fix, but I am just not seeing it.

Any suggestions??

I have tried the AtomicBoolean array, but it has not helped. Below is the same class but with the AtomicBoolean array implemented.

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class Assign7Q3 implements Runnable
{
private static int[] array;
private static AtomicInteger[] count;
private static AtomicBoolean[] check;

public Assign7Q3(int[] array, AtomicInteger[] count)
{
    this.array = array;
    this.count = count;
    this.check = new AtomicBoolean[array.length];
    for(int i = 0; i < check.length; i ++)
        check[i] = new AtomicBoolean(false);
}

public void run()
{
    for (int i = 0; i < array.length; i++)
    {
        //System.out.println(this.check[i].get());
        if (!getIndex(this.check[i]))
        {
            this.check[i].set(true);
            int number = array[i];
            count[number].incrementAndGet();
        }
    }
}

public synchronized static boolean getIndex(AtomicBoolean check2)
{
    return check2.get();
}
7
  • 1
    Would you mind explaining the problem? Commented Apr 14, 2016 at 22:36
  • I think the problem is in the boolean check array of checking. I have a feeling that multiple threads access the same boolean check array index at the same time. @YassinHajaj Commented Apr 14, 2016 at 22:41
  • Correct. Switch it to AtomicBoolean, yes? Commented Apr 14, 2016 at 22:43
  • It will help you out considerably to define your shared state as its own thread-safe class. Call it Histogram. Instantiate a single instance and pass that single instance to all your thread objects in the constructor. This will separate the concerns of thread-safety and the business logic of your threads. It'll be easier to conceptualise and you'll end up with a reusable histogram. Commented Apr 14, 2016 at 22:43
  • 1
    I have edited the original post, and it now encompasses the use of the AtomicBoolean @Radiodef Commented Apr 14, 2016 at 23:13

1 Answer 1

3

You need to use compareAndSet for your if statement to be mutally exclusive:

if (this.check[i].compareAndSet(false, true))
{
    int number = array[i];
    count[number].incrementAndGet();
}

This both checks and sets the value atomically.

Without compareAndSet, there is a possibility that two threads can check the value and enter the if block at the same time before one has a chance to call set(true).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, I did not realize that. Much appreciated

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.