在原子整数数组

时间:2016-04-14 22:34:40

标签: java arrays multithreading thread-synchronization

我正在编写代码让4个线程构建直方图。

我在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);
}

所以基本上我想做的就是遍历这个数组并计算每个数字出现的次数。

所以我编写了我的线程类,并且使用了AtomicInteger,我认为这有助于解决多个线程试图同时访问同一个索引的问题。

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;
}

然而,这并没有解决我的问题。有些线程同时访问数组,使count数组的值大于array数组的长度。

我认为问题在于检查的布尔数组。我有一种感觉,多个线程同时访问相同的布尔数组索引。

我认为这可能是一个简单的修复,但我只是没有看到它。

有什么建议吗?

我尝试了AtomicBoolean数组,但它没有帮助。下面是同一个类,但实现了AtomicBoolean数组。

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();
}

1 个答案:

答案 0 :(得分:2)

您需要使用compareAndSetif声明置于互斥:

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

这两者都会检查并以原子方式设置值。

如果没有compareAndSet,两个线程可能会检查该值并同时输入if块,然后才有机会调用set(true)