博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于hashtable线程安全的一个关键字和一段代码

Posted on 2007-07-23 16:29  吴博  阅读(524)  评论(0)    收藏  举报
一,关键字:
Synchronized

二:代码
近日有一些关于数据库并发控制的随笔.
我个人只是看过一些资料,并没有对数据库并发做过实验.所以也不能给出什么太好的解决方案.
不过这里有一个有关解决hashtable的线程安全的方法, 可能有一些参考价值.

有关HashTable的操作很简单,只是想实现读取HashTable中的一项,然后存入数据库中.只不过比往常不同的是要考虑线程的安全性问题.

最简单的解决办法就是在此期间锁住整个HashTable
lock(hashtable) {
  Item item 
= (Item)hashtable[key];
  item.SetName(
"foo");
  database.Persist(item);
}

显然这个方法不是很好,就象你不应该为了修改DataSet中的一项而锁住整个DataSet.这样做效率太低.

于是就转而去锁要修改的项
1    Item item = (Item)hashtable[key];
2    lock(item) {
3    item.SetName("foo");
4   database.Persist(item);
5     }

但是这样的话 就不再线程安全了.从line 1到line 2这期间万一其他线程对HashTable做了修改或是删除了改Item怎么办, 你再将结果存入数据库时岂不是覆盖了新的Item值,甚至多出了原本被(别的线程)删除的Item.

比较好的解决方法:
Item item = null;
bool lockWasSuccessful = false;

while(true{
    
lock(hashtable) {
        item 
= hashtable[key];
        lockWasSuccessful 
= Monitor.TryEntry(item);
    }

    
if(lockWasSuccessful == false{
        Thread.Sleep(
0);
        
continue;
    }

// If we reach here, the item was successfully locked
    try {
// Application code goes here
    }

    
finally {
        Monitor.Exit(item);
    }

    
break;
}



这里使用了lock和Monitor结合的方法.
先lock住整个HashTable, 不过时间很短.lock的目的仅仅是获得进入Item的权限.
如果此时没有其他线程在操作该Item,就立即释放lock进行操作.如果有其他线程在操作,Monitor.TryEntry(item)就会返回false.使得你无法进入该Item
也就保证了安全,同时lock整个HashTable的时间也得到了缩短.效率上得到了提高.

希望这个例子对大家有没有帮助.
http://www.cnblogs.com/idior/archive/2005/04/03/130095.html