C# threading and synchronizing methods So I started this question, I believe i have synchronized the methods correctly, need some insight on whats wrong and what should be done. I have to modify ths class Purse  so that the method AddCoin is synchronized and  implement a synchronized RemoveCoin method with a Coin argument, I believe that is done just fine. Where im really having trouble is implementing thread that adds pennies, another thread that adds quarters, and another thread that removes and prints randomly selected coins, pennies, quarters, any one. Then finally synchronize the threads to wait for each other when necessary. Here is what I have so far:
Purse.cs
using System;
using System.Collections;
using System.Threading;

namespace TestingProject
{
    /// &lt;summary&gt;
    /// A purse holds a collection of coins.
    /// &lt;/summary&gt;
public class Purse
{
    ///  Constructs an empty purse.
    public Purse()
    {
        coins = new ArrayList();

    }

    ///   Add a coin to the purse.
    ///   @param aCoin the coin to add
    public void Add(Coin aCoin)
    {
        Monitor.Enter(coins);
        coins.Add(aCoin);
        
        Monitor.Exit(coins);
    }
    public void RemoveCoin(Coin aCoin)
    {
        Monitor.Enter(coins);
        coins.Remove(aCoin);
        
        Monitor.Exit(coins);
    }
    

    ///  Get the total value of the coins in the purse.
    ///  @return the sum of all coin values
    public double GetTotal()
    {
        double total = 0;
        for (int i = 0; i &lt; coins.Count; i++)
        {
            Coin aCoin = (Coin)coins[i];
            total = total + aCoin.GetValue();
        }
        return total;
    }

    private ArrayList coins;
}



}

Coin.cs
using System;
using System.Collections;

namespace TestingProject
{
    /// &lt;summary&gt;
    /// A coin with a monetary value.
    /// &lt;/summary&gt;
public class Coin   {

    /// Constructs a coin.
    /// @param aValue the monetary value of the coin
    /// @param aName the name of the coin
    public Coin(double aValue, String aName) 
    { 
        value = aValue; 
        name = aName;
    }

    public Coin()
    {
    }

    /// Gets the coin value.
    /// @return the value
    public double GetValue()    
    {
        return value;
    }

    /// Gets the coin name.
    /// @return the name
    public String GetName() 
    {
        return name;
    }
    
    public override bool Equals(Object otherObject)
    {
        Coin other = (Coin)otherObject;
        return name==other.name
            &amp;&amp; value == other.value;
    }

    // C# requirement: 
    // since we override Equals, MUST also override GetHashCode ( !! )
    public override int GetHashCode()
    {
        return base.GetHashCode ();
    }

    private double value;
    private string name;
}
}

pursetest.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualBasic;


namespace TestingProject
{


class PurseTest
{
    public static void Main(string[] args)
    {
        

        // Random object used by each thread
        Random random = new Random();

        
        Purse purse =new Purse();

        Coin coin = new Coin();

        // output column heads and initial buffer state
        Console.WriteLine(&quot;{0,-35}{1,-9}{2}\n&quot;,
           &quot;Operation&quot;, &quot;Buffer&quot;, &quot;Occupied Count&quot;);


        
        Thread purseThread =
           new Thread(new ThreadStart(purse.Add))
           {
               Name = &quot;Purse&quot;
           };

        Thread coinThread =
           new Thread(new ThreadStart(coin.GetValue));
        coinThread.Name = &quot;coin&quot;;

        // start each thread
        purseThread.Start();
        coinThread.Start();

    }
}
}
Taking a look at your Coin class, there are a few things that aren't quite idiomatic C#.
The most obvious thing is that you're using what looks nearly like Java Doc comments. C# uses XML doc comments so this:
/// Constructs a coin.
/// @param aValue the monetary value of the coin
/// @param aName the name of the coin

Should be:
/// &lt;summary&gt;Constructs a Coin.&lt;/summary&gt;
/// &lt;param name=&quot;aValue&quot;&gt;The monetary value of the Coin.&lt;/param&gt;
/// &lt;param name=&quot;aName&quot;&gt;The name of the Coin.&lt;/param&gt;

In C#, we have properties which mean you don't need to write explicit GetXyz and SetXyz. I'm not sure whether you're using an old version of .Net (e.g. using ArrayList) but it's normal to have those as auto-implemented properties like this:
 public double Value { get; }
 public string Name { get; }

If you can't use auto-properties, you'll have to do a bit more typing. I'm going to assume you're stuck on an older .Net and try to avoid newer features.
private readonly double value;
public double Value 
{
    get
    {
        return value;
    }
}

That means you get rid of GetValue and GetName methods. I'd also suggest that you remove the empty constructor to force creation with a value and a name. That only leaves your Equals and GetHashcode implementations.
Let's consider a couple of test cases:
new Coin().Equals(&quot;blah&quot;); // InvalidCastException :(
new Coin().Equals(null); // NullReferenceException :(

Oh dear, we've got a problem here! Let's fix those bugs:
public override bool Equals(Object otherObject)
{
    return Equals(otherObject as Coin);
}

public bool Equals(Coin coin)
{
    if (ReferenceEquals(null, coin))
         return false;

    return coin.Value == this.Value &amp;&amp; coin.Name == this.Name;
}

That's nice and clear and most importantly, is correct! This is a common pattern and you can implement IEquatable at the same time if you want.
I think a coin should have a name in your model so you should validate that in the constructor.
So we're up to here:
/// &lt;summary&gt;
/// A coin with a monetary value.
/// &lt;/summary&gt;
public class Coin : IEquatable&lt;Coin&gt;
{
    private readonly double value;
    
    public double Value
    {
        get
        {
            return value;
        }
    }
    
    private string name;
    
    public string Name 
    {
        get
        {
            return name;
        }
    }

    /// &lt;summary&gt;Constructs a coin.&lt;/summary&gt;
    /// &lt;param name=&quot;value&quot;&gt;The monetary value of the Coin&lt;/param&gt;
    /// &lt;param name=&quot;name&quot;&gt;The name of the Coin&lt;/param&gt;
    public Coin(double value, string name)
    {
        if (name == null)
            throw new ArgumentNullException(&quot;name&quot;);
        this.value = value;
        this.name = name;
    }

    public override bool Equals(Object otherObject)
    {
        return Equals(otherObject as Coin);
    }

    public bool Equals(Coin coin)
    {
        if (ReferenceEquals(null, coin))
            return false;

        return coin.Value == this.Value &amp;&amp; coin.Name == this.Name;
    }
    
    // C# requirement: 
    // since we override Equals, MUST also override GetHashCode ( !! )
    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
    
}

So, only one thing left to talk about: GetHashCode. We must override GetHashCode and implement it correctly. I'll link you to this SO post: https://stackoverflow.com/questions/371328/why-is-it-important-to-override-gethashcode-when-equals-method-is-overridden
Your GetHashCode should look like this:
public override int GetHashCode()
{
    int hash = 13;
    hash = (hash * 7) + Value.GetHashCode();
    hash = (hash * 7) + Name.GetHashCode();
    return hash;
}

Now we've got a class that correctly implements equality.
ETA:
As has been pointed out in the comments, value is a contextual keyword so you may want to think twice before calling a field value. I don't see the problem myself as syntax highlighting in VS, for example, would know it wasn't a keyword. Calling it theValue would be worse for readability in my opinion. If you're on C# 6 or later, you should prefer the auto property so you don't need the field. Either way, if you write this class well at the beginning, the field is an implementation detail and you'll never read this source code again.