2016-04-14 3 views
0

Я пишу код, чтобы 4 потока создавали гистограмму.с использованием потоков в массиве Atomic Integer

У меня есть массив в основном:

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

Я думаю, проблема в контрольном массиве 'boolean'. У меня такое чувство, что несколько потоков одновременно обращаются к одному и тому же индексу массива контрольных массивов «boolean». @YassinHajaj –

+0

Исправить. Переключитесь на 'AtomicBoolean', да? –

ответ

2

Вы должны использовать compareAndSet для if заявления быть mutally эксклюзивными:

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

Это и проверяет и устанавливает значение атомарно.

Без compareAndSet существует вероятность того, что два потока могут проверить значение и ввести блок if в то же самое время, прежде чем у вас есть возможность позвонить set(true).

+0

Большое спасибо, я этого не осознавал. Очень признателен –

 Смежные вопросы

  • Нет связанных вопросов^_^