Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在无限循环中使用线程锁?_C#_Multithreading_Thread Safety - Fatal编程技术网

C# 如何在无限循环中使用线程锁?

C# 如何在无限循环中使用线程锁?,c#,multithreading,thread-safety,C#,Multithreading,Thread Safety,一般来说,我对线程技术相当陌生,我想在C#中尝试一下。我试图对每20秒腐烂一次,每10秒重新填充一次的东西的吨位做一个基本的模拟。从我所读到的,线程安全是我需要考虑的,因为有两个线程;一个用于将可变吨位衰减160,一个用于向吨位添加随机数量,由于他们正在对可变吨位进行交易,我应该确保正确访问它们 我阅读了如何使用lock(object),我理解了简单线程示例的概念,但是如何将它用于永久运行的两个线程,并且必须及时调整负载 这就是我所拥有的,但是当我锁定整个循环时,另一个线程永远不会生成。还是我有

一般来说,我对线程技术相当陌生,我想在C#中尝试一下。我试图对每20秒腐烂一次,每10秒重新填充一次的东西的吨位做一个基本的模拟。从我所读到的,线程安全是我需要考虑的,因为有两个线程;一个用于将可变吨位衰减160,一个用于向吨位添加随机数量,由于他们正在对可变吨位进行交易,我应该确保正确访问它们

我阅读了如何使用lock(object),我理解了简单线程示例的概念,但是如何将它用于永久运行的两个线程,并且必须及时调整负载

这就是我所拥有的,但是当我锁定整个循环时,另一个线程永远不会生成。还是我有错误的代码结构

public double tonnage = 1000;
private object x = new object(); 

//Starts the simulation, runs forever until user ends the simulation
private void btnStart_Click(object sender, EventArgs e)
{
    //Decay Tonnage
    Thread decayTonnageThread = new Thread(() => decayTonnage (tonnage));
    decayTonnageThread .Start();

    //Add Tonnage
    Thread addTonnageThread = new Thread(() => addTonnage (tonnage));
    addTonnageThread .Start();
}

//I want to decay the tonnage every 20 seconds
public void decayTonnage (double tonnage)
    {
        lock(x)
        {
            while (true)
            {
                tonnage = tonnage - 160;
                Thread.Sleep(20000);
            }
        }
    }

//Add to the tonnage every 10 seconds
public void addTonnage (double tonnage)
    {
        lock(x)
        {
            while (true)
            {
                Random random = new Random();
                double randomNumber = random.Next(97, 102);
                tonnage = tonnage + randomNumber;
                Thread.Sleep(10000);
            }
        }
    }

您希望锁尽可能小,只在与共享对象交互的线周围有锁,而不是整个循环。另外,放置
Random Random=new Random()
在while循环中,您应该只创建一个随机实例,并在循环外初始化它

//I want to decay the tonnage every 20 seconds
public void decayTonnage (double tonnage)
{

        while (true)
        {
            lock(x)
            {
                tonnage = tonnage - 160;
            }
            Thread.Sleep(20000);
        }
}

//Add to the tonnage every 10 seconds
public void addTonnage (double tonnage)
{

        Random random = new Random();
        while (true)
        {
            double randomNumber = random.Next(97, 102);
            lock(x)
            {
                tonnage = tonnage + randomNumber;
            }
            Thread.Sleep(10000);
        }
}

另外,我假设您这样做是为了某种分配,并且必须使用线程,但是如果我真的这样做,我根本不会使用循环+a
Sleep
的线程,而是使用两个计时器,一个每20秒触发一次,另一个每10秒触发一次。根据具体情况,您可能需要也可能不需要使用锁。

您希望在环路内部而不是外部进行锁定。仅在更改吨位时使用锁,排除代码的其余部分。也许用电脑是个好方法idea@adv12成功了,谢谢@Jeroen如果您使用的是
lock
它不是必需的,
lock
引入了一个完整的内存围栏,因此读取
吨位
的值应该是安全的@Jeroen我也将查看联锁类。谢谢你的建议我会试试这个,是的,我认为只锁定与共享对象交互的行是有意义的。它不是为了一项任务,而是为了工作(尚未投入生产)。我试图模拟如果用户改变一些变量会发生什么,所以我选择了线程。我会研究你关于使用计时器的建议,谢谢。