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();
}
}
}
我不知道我的代码有什么问题:
是class问题共享的数据(公式列表,和属性Id),我只需要锁定它的访问权限?
我是否需要担心 ProblemsRunner,并将整个对象锁定在 ProblemsRunner.RunProblem() foreach 循环中?
因为经过计算,我需要知道每个对象的Id和Formula,我不知道如何用多线程来实现。
您不需要更正所有代码(但请放心),我正在寻求解决此问题的一些指导,并实现线程安全...在 class 正确
您的代码似乎没有您担心的任何问题。每个问题都有自己的 Formulas
,因此当您在解决问题后添加新公式时,您不会访问可能从另一个线程访问的任何内容。
不过我怀疑这不是您想要的。你可能想要一个 Formulas
;在那种情况下,您当然需要一个线程安全列表。
您应该使用某种线程安全的阻塞队列来管理要解决的问题,并让每个线程在完成当前问题后从队列中取出另一个问题。当前向每个线程发送 10 个的方法的问题是,如果前 10 个比接下来的 10 个更快地解决,您的第一个线程将闲置。如果您在线程空闲时动态分配,您将让所有线程一直处于忙碌状态(最后除外)。
我正在学习多线程,但是我不知道如何在我的学习场景中实现线程安全。
这是一个伪代码,所以我有一个 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();
}
}
}
我不知道我的代码有什么问题:
是class问题共享的数据(公式列表,和属性Id),我只需要锁定它的访问权限?
我是否需要担心 ProblemsRunner,并将整个对象锁定在 ProblemsRunner.RunProblem() foreach 循环中?
因为经过计算,我需要知道每个对象的Id和Formula,我不知道如何用多线程来实现。
您不需要更正所有代码(但请放心),我正在寻求解决此问题的一些指导,并实现线程安全...在 class 正确
您的代码似乎没有您担心的任何问题。每个问题都有自己的 Formulas
,因此当您在解决问题后添加新公式时,您不会访问可能从另一个线程访问的任何内容。
不过我怀疑这不是您想要的。你可能想要一个 Formulas
;在那种情况下,您当然需要一个线程安全列表。
您应该使用某种线程安全的阻塞队列来管理要解决的问题,并让每个线程在完成当前问题后从队列中取出另一个问题。当前向每个线程发送 10 个的方法的问题是,如果前 10 个比接下来的 10 个更快地解决,您的第一个线程将闲置。如果您在线程空闲时动态分配,您将让所有线程一直处于忙碌状态(最后除外)。