在原子整数数组上使用线程
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
块。
我正在编写代码让 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
块。