C# 用三个线程访问三个列表,按顺序打印项目

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

问题是:

假设有3个相同长度的列表l1、l2和l3。三个线程访问三个列表。说T1->l1,T2->l2和T3->l3。它应该按如下顺序打印:第一个列表的第一个元素,第二个列表的第一个元素,第三个列表的第一个元素。然后是第一个列表的第二个元素,然后是第二个列表的第二个元素,然后是第三个列表的第二个元素

我尝试的是:

 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: