论坛首页 Java企业应用论坛

提问:关于线程安全性的问题

浏览 5935 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-01-17  
举个例子:
一个教师类中包含了多个学生,如果该教师类已经被cache缓存了,
那么如果有两个操作正在同时进行,一个操作在遍历该教师的学生,
而另一个操作在删除该教师的某个学生,
那么,是否会有线程不安全的问题呢?
   发表时间:2004-01-17  
不知我的意思表达清楚了没有,我是在看
http://www-900.ibm.com/developerWorks/cn/java/j-jtp09263/index.shtml
这篇文章的时候忽然想到的,因为hibernate底层提供了cache机制,那么在多线程环境下,就有可能有多个人同时拿到了教师类的同一个实例,那么如果有人在删除一个学生,而另一个人在遍历学生时,就很可能会出问题,不知hibernate是如何解决的?
0 请登录后投票
   发表时间: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);;
		}
	}

0 请登录后投票
   发表时间:2004-01-18  
从这些代码来看,好象在get和put时,都是需要同步的,这样的话,在大量的并发请求的处理上,不知会不会对性能有所影响?

而且,我前面疑惑的问题的关键并不是在get方法的同步问题上,
我的疑惑是:如果有两个并发用户都通过cache拿到了教师的同一个实例,那么如果有一个用户在遍历该教师的所有学生,而另一个用户正巧删除了某个学生,这样是否会产生并发问题?
因为通过Iterator进行遍历时,该遍历器是不允许被删除或新增元素的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics