I have to shuffle an array by swapping random index elements in parallel.
My question is how to prevent other threads from reading and writing elements that are currently being swapped by another thread. I don’t want to lock the entire array while one thread is swapping.
I would like to let couple threads swapping different pairs o elements in the same time.
I tried something like this :
object[] lockArray = new object[array.Length];
for (int i = 0; i < array.Length; i++)
lockArray[i] = new object();
for (int i = 0; i < thredCount; i++)
{
Thread t = new Thread(th => Shuffle.Shuflle(array,lockArray));
t.Start();
}
public class Shuffle
{
public static void Shuflle(char[] array,object [] lockArray)
{
for (int count = array.Length - 1; count > 1; count--)
{
Random rand = new Random();
int y = rand.Next(count) + 1;
lock (lockArray[count])
{
lock (lockArray[y])
{
char temp = array[count];
array[count] = array[y];
array[y] = temp;
}
}
}
}
}
In the array there are digits as chars from 0 to 9,
the result is reordered digits.
But sometimes I get result with one doubled ex. 138952469. 9 is now doubled in shuffled array and 7 is missing.
Please help me diagnose the problem.
What about not using locks at all:
the sentinel is just some dummy object that is shared between all the threads doing swapping and used to “reserve” a position for swapping.
The runs result on my laptop (i7):
The nConflict is the number of times the swap fails to reserve the position. It is rather low compared to the total number of swaps, so I optimized the routine for the case where there is no conflict only calling the SpinUntil when the conflict occurs.
The whole code I tested against: