惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google Online Security Blog
Google Online Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
Cisco Talos Blog
Cisco Talos Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Scott Helme
Scott Helme
Project Zero
Project Zero
E
Exploit-DB.com RSS Feed
S
Secure Thoughts
K
Kaspersky official blog
L
Lohrmann on Cybersecurity
NISL@THU
NISL@THU
WordPress大学
WordPress大学
N
News and Events Feed by Topic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LINUX DO - 热门话题
小众软件
小众软件
P
Privacy & Cybersecurity Law Blog
博客园 - 聂微东
Google DeepMind News
Google DeepMind News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
About on SuperTechFans
Hacker News: Ask HN
Hacker News: Ask HN
AWS News Blog
AWS News Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Hacker News: Front Page
F
Full Disclosure
Latest news
Latest news
Schneier on Security
Schneier on Security
The Hacker News
The Hacker News
T
Troy Hunt's Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Jina AI
Jina AI
Martin Fowler
Martin Fowler
P
Proofpoint News Feed
TaoSecurity Blog
TaoSecurity Blog
G
GRAHAM CLULEY
Forbes - Security
Forbes - Security
V
V2EX - 技术
酷 壳 – CoolShell
酷 壳 – CoolShell
V
Vulnerabilities – Threatpost
C
Cyber Attacks, Cyber Crime and Cyber Security
MongoDB | Blog
MongoDB | Blog
博客园 - 三生石上(FineUI控件)
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
P
Privacy International News Feed
C
Check Point Blog
N
News and Events Feed by Topic

博客园 - xvhfeng

blog搬迁 2012 年度总结 2011年年度总结 albian使用方法-1 albian开发笔记六-albian的架构 albian开发笔记五--谈缓存同步 albian开发笔记四 albian开发笔记三 albian开发笔记二 albian开发笔记一 Albian开发库的设计与规划 《程序员入职锦囊妙计》终于完成了 FastMQ V0.2.0 stable版发布 实现线程内同一对象 发现你的优势测评结果 DFS架构 FastMQ V0.1.1使用方法 开源消息队列FastMQ V0.1.0 发布 linux环境C编程的血泪教训
hashTable和多线程问题
xvhfeng · 2011-07-21 · via 博客园 - xvhfeng

  刚刚被一同事叫去看一个问题,问题的表象是程序会周期性的报“集合被修改,循环无法继续”的异常,查了半天的问题,最后找到问题如下:

     因为本地缓存很少过期,所以我们就将本地的缓存全部放入hashtable中,而hashtable中的value一般情况下就是IList<T>类型,而hashtable中的数据也不是一定不过期,所以我们就增加了缓存的更新功能,好了,问题出现了。

  代码大致是这样的

      private readonly static hashtable ht = hashtable.sync(new hashtable());

      public static hashtable Cache{return ht;};

      这个代码是在我们的缓存类中的,下面的代码是引用的地方:

     IList<T> list = Cache["key"] as IList<T>;

     foreach(T obj in list)

  {

          do somthing;

  }

     看看代码,好像没有你问题,但是真的运行起来就不是那么一回事情了。

     这里的问题出在我们的一个思维定势。ht是线程安全的,但是ht中value不一定,这是主因。从代码中可以看出来,value存放是IList,那么存放的应该是引用(也就是指针),而当我们通过索引器得到这个IList时,这部操作是线程安全的,但是到这里的安全并不意味着foreach也是安全的。因为hashtable提供的线程安全功能已经完成了,foreach已经是在脱离了hashtable的线程安全运行的。所以问题就会出现了。IList是引用类型,所以我们foreach的Ilist只是一个指针,具体的值存放在IList指针指向的地方,而当我们正好在更新hashtable中的foreach中指定的那个IList的时候,这个IList的指针变改变了,所以就会报错;

     解决问题的办法就是增加一个结构体,这个结构体中有两个对象:

     struct Item{object locker;IList list;},这样,每次更新或者循环的时候都要先加上locker的锁,这样就可以避免了线程的我安全问题!