在原子整数数组上使用线程

using threads on an Atomic Integer Array

我正在编写代码让 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);
}

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

所以我写了我的线程 class,我使用了 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 数组,但没有用。下面是相同的 class,但实现了 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();
}

您需要使用 compareAndSet 才能让您的 if 语句互斥:

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

这会自动检查和设置值。

如果没有compareAndSet,有可能两个线程在一个线程有机会调用set(true)之前同时检查值并进入if块。