浏览 5935 次
锁定老帖子 主题:提问:关于线程安全性的问题
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-01-17
一个教师类中包含了多个学生,如果该教师类已经被cache缓存了, 那么如果有两个操作正在同时进行,一个操作在遍历该教师的学生, 而另一个操作在删除该教师的某个学生, 那么,是否会有线程不安全的问题呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-01-17
不知我的意思表达清楚了没有,我是在看
http://www-900.ibm.com/developerWorks/cn/java/j-jtp09263/index.shtml 这篇文章的时候忽然想到的,因为hibernate底层提供了cache机制,那么在多线程环境下,就有可能有多个人同时拿到了教师类的同一个实例,那么如果有人在删除一个学生,而另一个人在遍历学生时,就很可能会出问题,不知hibernate是如何解决的? |
|
返回顶楼 | |
发表时间:2004-01-18
Hibnerate uses lock and version for this:
see net.sf.hibernate.cache.ReadWriteCache /** * Do not return an item whose timestamp is later than the current * transaction timestamp. (Otherwise we might compromise repeatable * read unnecessarily.); Do not return an item which is soft-locked. * Always go straight to the database instead.<br> * <br> * Note that since reading an item from that cache does not actually * go to the database, it is possible to see a kind of phantom read * due to the underlying row being updated after we have read it * from the cache. This would not be possible in a lock-based * implementation of repeatable read isolation. It is also possible * to overwrite changes made and committed by another transaction * after the current transaction read the item from the cache. This * problem would be caught by the update-time version-checking, if * the data is versioned or timestamped. */ public synchronized Object get(Object key, long txTimestamp); throws CacheException { if ( log.isTraceEnabled(); ); log.trace("Cache lookup: " + key);; try { cache.lock(key);; Lockable lockable = (Lockable); cache.get(key);; boolean gettable = lockable!=null && lockable.isGettable(txTimestamp);; if (gettable); { if ( log.isTraceEnabled(); ); log.trace("Cache hit: " + key);; return ( (Item); lockable );.getValue();; } else { if ( log.isTraceEnabled(); ); { if (lockable==null); { log.trace("Cache miss: " + key);; } else { log.trace("Cached item was locked: " + key);; } } return null; } } finally { cache.unlock(key);; } } and /** * Do not add an item to the cache unless the current transaction * timestamp is later than the timestamp at which the item was * invalidated. (Otherwise, a stale item might be re-added if the * database is operating in repeatable read isolation mode.); */ public synchronized boolean put(Object key, Object value, long txTimestamp); throws CacheException { if ( log.isTraceEnabled(); ); log.trace("Caching: " + key);; try { cache.lock(key);; Lockable lockable = (Lockable); cache.get(key);; boolean puttable = lockable==null || lockable.isPuttable(txTimestamp);; if (puttable); { cache.put( key, new Item( value, cache.nextTimestamp(); ); );; if ( log.isTraceEnabled(); ); log.trace("Cached: " + key);; return true; } else { if ( log.isTraceEnabled(); ); { if ( lockable.isLock(); ); { log.trace("Item was locked: " + key);; } else { log.trace("Item was already cached: " + key);; } } return false; } } finally { cache.unlock(key);; } } |
|
返回顶楼 | |
发表时间:2004-01-18
从这些代码来看,好象在get和put时,都是需要同步的,这样的话,在大量的并发请求的处理上,不知会不会对性能有所影响?
而且,我前面疑惑的问题的关键并不是在get方法的同步问题上, 我的疑惑是:如果有两个并发用户都通过cache拿到了教师的同一个实例,那么如果有一个用户在遍历该教师的所有学生,而另一个用户正巧删除了某个学生,这样是否会产生并发问题? 因为通过Iterator进行遍历时,该遍历器是不允许被删除或新增元素的 |
|
返回顶楼 | |