在类中使用状态和可变对象的多线程计算
本文关键字:对象 多线程 计算 状态 | 更新日期: 2023-09-27 18:35:52
我正在学习多线程,但是我不知道如何在我的研究场景中实现线程安全。
这是一个伪代码,所以我有一个类,可以执行一些计算并共享一些公共数据(公式列表),并且有一个公共属性 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 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)和我只需要锁定其访问权限吗?
我是否需要在 ProblemRunner 中担心,并将整个对象锁定在 ProblemRunner.RunProblem() foreach 循环中?
因为经过计算,我需要知道每个对象的 Id 和公式,而我无法弄清楚如何使用多线程来做到这一点。
你不需要纠正所有代码(但请随意),我要求一些方向来解决这个问题,并实现线程安全......在类相关内具有状态和可变对象
您的代码似乎没有任何您担心的问题。每个问题都有自己的Formulas
,因此当您在解决问题后添加新公式时,您不会访问可能从另一个线程访问的任何内容。
不过,我怀疑这不是您的意图。你可能想要一个Formulas
;在这种情况下,您当然需要一个线程安全列表。
您应该使用某种线程安全的阻塞队列来管理要解决的问题,并让每个线程在完成当前线程时从队列中取出另一个。您当前向每个线程发送 10 个线程的方法的问题在于,如果前 10 个线程的解决速度比后 10 个线程快,则第一个线程将闲置。如果在线程空闲时动态分配,则所有线程将一直处于繁忙状态(最后除外)。