Методы синхронизации C# и многопоточность
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 { /// <summary> /// A purse holds a collection of coins. /// </summary> 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 < 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 { /// <summary> /// A coin with a monetary value. /// </summary> 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 && 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("{0,-35}{1,-9}{2}\n", "Operation", "Buffer", "Occupied Count"); Thread purseThread = new Thread(new ThreadStart(purse.Add)) { Name = "Purse" }; Thread coinThread = new Thread(new ThreadStart(coin.GetValue)); coinThread.Name = "coin"; // start each thread purseThread.Start(); coinThread.Start(); } } }
honey the codewitch
Я не буду публиковать это в качестве ответа, потому что это не так, но вам будет гораздо проще использовать задачи вместо потоков. Тогда вы можете просто ждать их
C#Learner12
Я согласен, но меня попросили использовать темы, а не задачи. Я не очень хорошо разбираюсь в нитях, этот вопрос поставил меня в тупик
honey the codewitch
Вы должны использовать объект ManualResetEvent для запуска, когда поток будет завершен. сделайте другой для каждого потока. Когда вам нужно подождать, позвоните Уэйтхэндлу.WaitAll() и передайте все это, если ваши объекты ManualResetEvent. Вы устанавливаете один из них с помощью Set(). Если вы сделаете WaitAll (), он будет ждать, пока все они не будут установлены.
Richard Deeming
ArrayList
это древний класс, который не должен использоваться ни в одном коде, написанном в течение последних 14 лет. Вы действительно должны использовать System.Collections.Generic.List<Coin>
, или какая-то другая общая коллекция.
То GetValue
и GetName
методы на Coin
класс действительно должен быть свойствами. С помощью Get*
методы, когда вы не делаете никакой сложной логики, больше похожи на Java.
Вам также не хватает блокировки внутри вашего устройства. Purse.GetTotal
метод - все остальное, что имеет доступ к coins
поле потокобезопасно, но этот метод-нет.
honey the codewitch
Ричард, я согласен с тобой, и я предполагаю, что его профессор кормит его .NET 1измами. И меня нисколько не удивляет, что это такое явальское имя, если оно выходит из школы. Похоже, что все эти кошки имеют дело с Явой, даже если они болтают на другом языке.