锁定问题 - 多线程使LOOP失序

Mag*_*age 2 c# multithreading locking task-parallel-library

我有一个示例应用程序,并想知道是否有人可以阐明这一点.当我在for循环上放置一个断点进入调试器中的代码时,为什么它从一个线程切换到另一个?在运行时运行应用程序时会这样做...请参阅下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TPLSample
{
    class Program
    {

        static void Main(string[] args)
        {
           Management m = new Management();

           Task a = new Task(() => m.Operation1());
           a.Start();
           Task b = new Task(() => m.Operation2());
           b.Start();


            Console.ReadLine();
        }
    }
    public class Management
    {
        A a = null;
        B b = null;

        public void Operation1()
        {
            a = new A();

        }
        public void Operation2()
        {
            b = new B();
        }
    }
    public class A
    {  Client a = new Client();
        public A()
        {
            while (true)
            {
                a.Test("Im AAAAA");
            }
        }
    }
    public class B
    {
        Client a = new Client();
        public B()
        {
            while (true)
            {
                a.Test("Im BBBBB");
            }
        }
    }
    public class Client
    {
        Object ibj = new Object();


        public void Test(string item)
        {
            lock (ibj)
            {
                for (int i = 0; i < 200000; i++)
                {
                    Console.WriteLine(item);
                }
            }

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是As和Bs的混合物.锁是否假设阻塞线程,结果将按顺序结束?在我正在编写的应用程序中也发生了同样的事情,除了WHILE循环永远运行(每个任务需要连续轮询).请注意,我正在启动两个任务,因为如果WHILE循环要永远运行,我不希望一个WHILE循环阻止另一个循环运行.如何使它们按顺序进入CLIENT类中的该函数?

Tud*_*dor 7

发生这种情况是因为如果您仔细跟踪对象创建树,您会注意到每个线程都使用不同的锁对象,从而使您的lock语句无效.

您的对象创建如下:

                 new A() -> new Client() -> new Object()
                / 
new Management()
                \
                 new B() -> new Client() -> new Object()
Run Code Online (Sandbox Code Playgroud)

您使用右侧的最后两个对象作为锁,您可以清楚地看到它们是不同的对象.

尝试使锁定静态:

public class Client
{
    static Object ibj = new Object();
    ...
Run Code Online (Sandbox Code Playgroud)

或重新考虑您的层次结构,以将相同的锁传递给两个任务.