我有一个WCF应用程序,它从客户端应用程序接收一些字符串数组。然后,这些数组作为参数传递给某些自定义类的构造函数。我不是,我自己,创建任何线程(甚至不使用System.Threading
),但我想知道在每个构造函数中使用lock (param.SyncRoot)
只是为了安全起见是不是很糟糕?那是因为我让我的所有对象都是不可变的,我想确保数组不会以任何方式改变。
答案 0 :(得分:2)
我认为你过分复杂了
使线程尽可能简单的主要事情之一是清楚地了解锁定的责任。因此,如果您不创建任何线程,则不需要锁定,锁定只会使事情变得复杂,但不会添加任何值 - 错误的库仍然会失败。
锁定应在您创建和使用的对象内完成。
答案 1 :(得分:1)
如果要使对象不可变,则必须创建数组的深层副本并将该副本存储在对象中。如果数组包含引用类型,则也不必公开该数组。在构造函数中锁定数组是不可能的(在using
语句中使用了锁 - 当语句结束时看起来也会结束)。此外,对象整个生命周期的锁定数组都是无稽之谈。
不变性本身与锁定无关。锁定是为了防止从多个线程同时访问您的对象 - 您提到您没有这样做。不可变性意味着您的对象具有状态且状态不能更改 - 它在构造函数中定义,并且在对象的整个生命周期内保持不变。在创建不可变对象时,它们不能与其他对象共享引用,并且它们不能公开对其状态的引用,因为这样可以修改它们的状态。
答案 2 :(得分:1)
如何使对象不可变与构造函数或将数据从一个对象传递到另一个对象无关。
一旦接收对象通过构造函数或其他方式获取数组,就可以将其泵入ReadOnlyCollection:
ReadOnlyCollection<Customer> _customers = new ReadOnlyCollection<Customer>(arrayPassedViaConstructor)
现在每个对象都有自己的,不可修改的数组副本。即使原始数组(在调用对象中)确实发生了变化,接收对象中的只读副本也不会。