8
|
Per Hornshøj-Schierbeck · 技术社区 · 16 年前 |
![]() |
1
11
锁定在代码锁定之外可访问的对象上是一个很大的风险。如果有任何其他代码(任何地方)锁定了该对象,您可能会遇到一些难以调试的死锁。还要注意,您锁定了 对象 ,而不是引用,所以如果我给你一本字典,我可能仍然保留对键的引用并锁定它们——这导致我们锁定同一个对象。 如果 您完全封装了字典,并自己生成密钥(它们从来没有被传入,那么您可能是安全的)。 但是,尽量遵循一个规则——尽可能限制锁定代码本身的对象的可见性。 这就是为什么你看到这个:
而不是看到上面的A行被替换为
这样,一个单独的对象被锁定,并且可见性受到限制。 编辑 Jon Skeet 正确地观察到上面的lockobj应该是只读的。 |
![]() |
2
8
不,这样不行。 原因是 string interning . 这意味着:
都是同一个对象!因此,您不应该锁定字符串,因为如果程序的其他部分(例如,同一对象的另一个实例)也希望锁定同一字符串,则可能会在不需要该字符串的情况下意外创建锁争用;甚至可能是死锁。 尽管如此,您可以使用非字符串来完成这项工作。为了清晰起见,我习惯于创建单独的锁对象:
我建议你也这么做。为每个矩阵单元创建一个带有锁对象的字典。然后,在需要时锁定这些对象。 另外,更改您正在迭代的集合被认为不是很好。它甚至会引发大多数集合类型的异常。尝试重构它——例如,迭代键列表,如果它总是常量,而不是成对的。 |
![]() |
3
3
注意:在迭代过程中修改集合时,我假定已经修复了异常 字典不是线程安全集合,这意味着它是 不 在没有外部同步的情况下,可以安全地从不同的线程修改和读取集合。哈希表是?线程安全,适用于一个编写器多个读卡器场景,但字典具有不同的内部数据结构,并且不继承此保证。 这意味着您不能在从另一个线程访问字典进行读或写时修改字典,它只会破坏内部数据结构。锁定密钥并不能保护内部数据结构,因为当您修改这个密钥时,可能有人在另一个线程中读取字典的不同密钥。即使你能保证你所有的钥匙都是一样的东西(比如说绳子被扣住),这也不能保证你的安全。例子:
如果字典中没有这样的键,第一个线程将开始修改列表,第二个线程可能会读取未完成状态。 如果已经存在这样的键,字典的实现细节仍然可以修改数据结构,例如,将最近访问的键移到列表的头部,以便更快地检索。您不能依赖实现细节。 有很多这样的情况,当你将损坏字典。因此,在整个操作过程中,您必须拥有外部同步对象(或者如果字典不公开,则使用字典本身)并对其进行锁定。如果在操作可能需要很长时间时需要更精细的锁,可以复制需要更新的键,迭代它,在单键更新期间锁定整个字典(不要忘记验证键是否仍然存在),然后释放它以让其他线程运行。 |
![]() |
4
2
如果我没有弄错,最初的目的是锁定一个元素,而不是锁定整个字典(比如表级锁和数据库中的行级锁)。 你不能像这里解释的那样锁定字典的钥匙。 您可以做的是保存一个锁对象的内部字典,它与实际的字典相对应。所以当你想写你的字典[key1]时,你首先会锁定internalLocksDictionary[key1]——所以只有一个线程会写你的字典。 一个(不太干净)的例子可以是 found here . |
![]() |
5
1
刚刚遇到这个问题,我想我可以分享几年前我写的一些代码,在那里我需要一本关键的字典。
锁类
|
![]() |
6
0
在你的例子中,你不能做你想做的! 你会得到一个 System.InvalidOperationException 带着…的信息 集合已修改;枚举操作可能无法执行。 下面是一个例子来证明:
输出将是:
|
![]() |
7
0
我可以看到一些潜在的问题:
|
![]() |
eymentakak · json字典类型错误:字符串索引必须是整数 2 年前 |
![]() |
Rohan Mittal · 按dict值对dict排序 2 年前 |
![]() |
mars · 将值作为元组对字典进行排序 2 年前 |
![]() |
Sher Meen · 我需要列出一个循环中临时变量中存储的多个值 2 年前 |
![]() |
Shubh · 如何将字典行附加到空数据帧中? 2 年前 |
![]() |
kms · 从pandas中的字典中读取数据并指定新的列值 2 年前 |
![]() |
Alex · 如何向嵌套字典json添加值? 2 年前 |