class 中状态和可变对象的多线程计算

Multithreading calculations with state and mutable objects in a class

我正在学习多线程,但是我不知道如何在我的学习场景中实现线程安全。

这是一个伪代码,所以我有一个 class 可以进行一些计算并共享一些 public 数据(公式列表),并且有一个 public 属性 ID 用于进一步阅读:

class Problem{
  public int Id {get; set;}
  public IList<Calc> Formulas {get; private set;}

  public Problem(int id){
    Id = id;
    Formulas = new List<Formulas>();
  }

  public void SolveProblem(){
    Calc newCalc = DoSomeCalculations();
    Formulas.Add(newCalc);
  }

  private Calc DoSomeCalculations(){
    var originalFormulas = Formulas.Where(x => x.Number > 2);
    return new Calc(originalFormulas);
  }
}

然后我做了 class 以通过多个线程运行大量计算:

class ProblemsRunner{
  public void Run(List<Problem> problemsToSolve){
    var thread1 = new Thread(RunProblem(problemsToSolve.Take(10)));
    var thread2 = new Thread(RunProblem(problemsToSolve.Skip(10).Take(10)));
    var thread3 = new Thread(RunProblem(problemsToSolve.Skip(20).Take(10)));

    thread1.Start();
    thread2.Start();
    thread3.Start();
  }

  private void RunProblem(IEnumerable<Problem> problems){
    foreach(var problem in problems){
      problem.SolveProblem();
    }
  }
}

我不知道我的代码有什么问题:

因为经过计算,我需要知道每个对象的Id和Formula,我不知道如何用多线程来实现。

您不需要更正所有代码(但请放心),我正在寻求解决此问题的一些指导,并实现线程安全...在 class 正确

您的代码似乎没有您担心的任何问题。每个问题都有自己的 Formulas,因此当您在解决问题后添加新公式时,您不会访问可能从另一个线程访问的任何内容。

不过我怀疑这不是您想要的。你可能想要一个 Formulas;在那种情况下,您当然需要一个线程安全列表。

您应该使用某种线程安全的阻塞队列来管理要解决的问题,并让每个线程在完成当前问题后从队列中取出另一个问题。当前向每个线程发送 10 个的方法的问题是,如果前 10 个比接下来的 10 个更快地解决,您的第一个线程将闲置。如果您在线程空闲时动态分配,您将让所有线程一直处于忙碌状态(最后除外)。