Here is the question:
Say there are 3 lists l1, l2 & l3 of same length. Three threads accessing three lists. Say T1 -> l1, T2 ->l2 & T3 ->l3. It should print in the order say first element of 1st then first element of 2nd list and then first element of 3rd list. Then second element of 1st then second element of 2nd list and then second element of 3rd list.
What I tried:
private static readonly Object obj = new Object();
static List<string> list1 = new List<string> { "1", "2", "3", "4" };
static List<string> list2 = new List<string> { "a", "b", "c", "d" };
static List<string> list3 = new List<string> { "*", "+", "-", "?" };
static int i = 0;
static void Main(string[] args)
{
Thread t1 = new Thread(() => PrintItem());
t1.Name = "Print1";
Thread t2 = new Thread(() => PrintItem());
t2.Name = "Print2";
Thread t3 = new Thread(() => PrintItem());
t3.Name = "Print3";
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join();
Console.Read();
}
private static void PrintItem()
{
while (true)
{
lock (obj)
{
if (i >= list1.Count)
break;
Console.WriteLine(Thread.CurrentThread.Name + " " + list1[i]);
Console.WriteLine(Thread.CurrentThread.Name + " " + list2[i]);
Console.WriteLine(Thread.CurrentThread.Name + " " + list3[i]);
i++;
}
}
}
The output is right but it doesn't use three threads. Correct the code please.
If it was me I would use EventWaitHandles to signal and synchronize your threads. In my code the Threads wait for a Signal and they then print out their current string and then wait to be signaled again:
static void Main(string[] args)
{
List<string> list1 = new List<string> { "1", "2", "3", "4" };
List<string> list2 = new List<string> { "a", "b", "c", "d" };
List<string> list3 = new List<string> { "*", "+", "-", "?" };
using (EventWaitHandle waitHandle1 = new AutoResetEvent(false))
using (EventWaitHandle waitHandle2 = new AutoResetEvent(false))
using (EventWaitHandle waitHandle3 = new AutoResetEvent(false))
using (EventWaitHandle waitHandle4 = new AutoResetEvent(false))
{
Thread t1 = new Thread(() =>
{
ThreadData state = new ThreadData()
{
Name = "Thread1",
Strings = list1,
WaitHandle = waitHandle1,
SignalHandle = waitHandle2
};
PrintItemWhenSignaled(state);
});
Thread t2 = new Thread(() =>
{
ThreadData state = new ThreadData()
{
Name = "Thread2",
Strings = list2,
WaitHandle = waitHandle2,
SignalHandle = waitHandle3
};
PrintItemWhenSignaled(state);
});
Thread t3 = new Thread(() =>
{
ThreadData state = new ThreadData()
{
Name = "Thread3",
Strings = list3,
WaitHandle = waitHandle3,
SignalHandle = waitHandle4
};
PrintItemWhenSignaled(state);
});
t1.Start();
t2.Start();
t3.Start();
for (int index = 0; index < list1.Count; index++)
{
waitHandle1.Set();
waitHandle4.WaitOne(100);
}
}
Console.WriteLine("Press any key...");
Console.ReadKey();
}
private static void PrintItemWhenSignaled(ThreadData threadState)
{
foreach (string value in threadState.Strings)
{
threadState.WaitHandle.WaitOne(100);
Console.WriteLine("{0}:{1}", threadState.Name, value);
threadState.SignalHandle.Set();
}
}
public class ThreadData
{
public string Name { get; set; }
public EventWaitHandle WaitHandle { get; set; }
public EventWaitHandle SignalHandle { get; set; }
public List<string> Strings { get; set; }
}
}