i_shoot_photos
i_shoot_photos

Reputation: 176

How do i use thread locks in an infinite loop?

I am fairly new to threading in general and i want to try it in C#. I am trying to make a basic simulation of tonnage of something which is decaying every 20 seconds and being refilled every 10 seconds. From what i read, thread safety is something i need to consider as there are two threads; one for decaying the variable tonnage by 160, one for adding a random amount to the tonnage and since they are making transactions to the variable tonnage, i should make sure they are accessed correctly.

I read on how to use lock(object) and i understand the concept for simple thread examples but how do i use it for 2 threads running forever and have to make timely adjustments in the tonnage?

Here is what i have, but when i lock the whole loop, the other thread never spawns. Or do i have the wrong code structure?

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);
            }
        }
    }

Upvotes: 2

Views: 1445

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127563

You want the lock to be as small as possible, only have it around the lines that are interacting with shared objects, not the entire loop. Also, putting Random random = new Random(); in the while loop is a bad habit to have, you should make only one random instance and initialize it outside of the loop.

//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);
        }
}

Also, I assume you are doing this for some kind of assignment and must use threads, but if I was doing this for real I would not use threads with loops + a Sleep at all and instead use two timers, one that fired every 20 seconds and one that fired every 10 seconds. Depending on the type of timer you use you may or may-not still need to use a lock.

Upvotes: 5

Related Questions