C# 用三个线程访问三个列表,按顺序打印项目
问题是: 假设有3个相同长度的列表l1、l2和l3。三个线程访问三个列表。说T1->l1,T2->l2和T3->l3。它应该按如下顺序打印:第一个列表的第一个元素,第二个列表的第一个元素,第三个列表的第一个元素。然后是第一个列表的第二个元素,然后是第二个列表的第二个元素,然后是第三个列表的第二个元素 我尝试的是:C# 用三个线程访问三个列表,按顺序打印项目,c#,multithreading,tpl-dataflow,C#,Multithreading,Tpl Dataflow,问题是: 假设有3个相同长度的列表l1、l2和l3。三个线程访问三个列表。说T1->l1,T2->l2和T3->l3。它应该按如下顺序打印:第一个列表的第一个元素,第二个列表的第一个元素,第三个列表的第一个元素。然后是第一个列表的第二个元素,然后是第二个列表的第二个元素,然后是第三个列表的第二个元素 我尝试的是: private static readonly Object obj = new Object(); static List<string> list1 = ne
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++;
}
}
}
private static readonly Object obj=new Object();
静态列表list1=新列表{“1”、“2”、“3”、“4”};
静态列表list2=新列表{“a”、“b”、“c”、“d”};
静态列表list3=新列表{“*”、“+”、“-”、“?”};
静态int i=0;
静态void Main(字符串[]参数)
{
线程t1=新线程(()=>PrintItem());
t1.Name=“Print1”;
线程t2=新线程(()=>PrintItem());
t2.Name=“Print2”;
线程t3=新线程(()=>PrintItem());
t3.Name=“Print3”;
t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.连接();
t3.Join();
Console.Read();
}
私有静态void PrintItem()
{
while(true)
{
锁(obj)
{
如果(i>=list1.Count)
打破
Console.WriteLine(Thread.CurrentThread.Name+“”+list1[i]);
Console.WriteLine(Thread.CurrentThread.Name+“”+list2[i]);
Console.WriteLine(Thread.CurrentThread.Name+“”+list3[i]);
i++;
}
}
}
输出是正确的,但它不使用三个线程。请更正代码。因为锁只有一个线程。。。最快的是第一个。。。您可以访问您的列表 删除lock语句或删除:
if (i >= list1.Count)
break;
条件,或使用属性使i
ThreadStatic
如果这是您的预期输出?
如果是我,我会使用EventWaitHandles发送信号并同步线程。在我的代码中,线程等待信号,然后打印出当前字符串,然后等待再次发出信号:
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; }
}
}
static void Main(字符串[]args)
{
list1=新列表{“1”、“2”、“3”、“4”};
List list2=新列表{“a”、“b”、“c”、“d”};
List list3=新列表{“*”、“+”、“-”、“?”};
使用(EventWaitHandle waitHandle1=new AutoResetEvent(false))
使用(EventWaitHandle waitHandle2=new AutoResetEvent(false))
使用(EventWaitHandle waitHandle3=new AutoResetEvent(false))
使用(EventWaitHandle waitHandle4=new AutoResetEvent(false))
{
线程t1=新线程(()=>
{
ThreadData状态=新的ThreadData()
{
Name=“Thread1”,
Strings=list1,
WaitHandle=waitHandle1,
SignalHandle=waitHandle2
};
已签名的打印项(状态);
});
线程t2=新线程(()=>
{
ThreadData状态=新的ThreadData()
{
Name=“Thread2”,
Strings=list2,
WaitHandle=waitHandle2,
SignalHandle=waitHandle3
};
已签名的打印项(状态);
});
线程t3=新线程(()=>
{
ThreadData状态=新的ThreadData()
{
Name=“Thread3”,
Strings=list3,
WaitHandle=waitHandle3,
SignalHandle=waitHandle4
};
已签名的打印项(状态);
});
t1.Start();
t2.Start();
t3.Start();
for(int index=0;index
虽然这是一个非常奇怪的要求,但一种很好的可扩展方式可能是使用Monitor.Pulse
和Monitor.Wait
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", "e" };
static List<string> list3 = new List<string> { "*", "+", "-", "?" };
static int i = 0;
//thread synchronization data
const int numThreads = 3;
static int workingCount = 0;
static int lastItem = 0;
static object locker = new object();
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(0);
t2.Start(1);
t3.Start(2);
t1.Join();
t2.Join();
t3.Join();
Console.ReadLine();
}
private static void PrintItem(object state)
{
Interlocked.Increment(ref workingCount);
int workingList = (int)state;
int idx = 0;
List<string> list = null;
switch (workingList)
{
case 0:
list = list1;
break;
case 1:
list = list2;
break;
case 2:
list = list3;
break;
}
lock (locker)
do
{
while ((lastItem % numThreads) != workingList)
{
Monitor.Wait(locker);
}
Console.WriteLine("Thread: {0}\tValue: {1}", Thread.CurrentThread.Name, list[idx]);
lastItem++;
Monitor.PulseAll(locker);
} while (++idx < list.Count);
//Handle continuing to pulse until all lists are done.
Interlocked.Decrement(ref workingCount);
lock (locker)
while (workingCount != 0)
{
while ((lastItem % numThreads) != workingList)
Monitor.Wait(locker);
lastItem++;
Monitor.PulseAll(locker);
}
}
}
private static readonly Object obj=new Object();
静态列表list1=新列表{“1”、“2”、“3”、“4”};
静态列表list2=新列表{“a”、“b”、“c”、“d”、“e”};
静态列表list3=新列表{“*”、“+”、“-”、“?”};
静态int i=0;
//线程同步数据
常量int numThreads=3;
静态整数工作计数=0;
静态int lastItem=0;
静态对象锁定器=新对象();
静态void Main(字符串[]参数)
{
螺纹t1=新螺纹(打印项);
t1.Name=“Print1”;
螺纹t2=新螺纹(打印项目);
t2.Name=“Print2”;
螺纹t3=新螺纹(打印项目);
t3.Name=“Print3”;
t1.启动(0);
t2.启动(1);
t3.启动(2);
t1.Join();
t2.连接();
t3.Join();
Console.ReadLine();
}
私有静态void打印项(对象状态)
{
联锁增量(参考工作计数);
int工作列表=(int)状态;
int-idx=0;
List=null;
开关(工作列表)
{
案例0:
列表=列表1;
打破
案例1: