关于是否需要同步的一个问题?

追风

有个问题不是很清楚,如果一个方法是用来从数据库中取数据的,然后返回一个ArrayList,如果多个线程同时访问该方法,是否需要同步?

jxb8901
2002-12-30 09:32

我理解一个方法是否要同步, 应该考量以下几点:
1. 是否会有多个线程同时访问一个对象(也就是调用同一个对象的方法), 注意这里指的是同一个对象, 而不是一个类的多个方法, 我开始总会混淆两者.
如果答案是"否", 就不需同步.
2. 若1的答案为"是", 还应该具体到对象的方法上. 某个方法是否会读写"类或全局"的成员变量. 若答案为"否", 也不需同步.
3. 即便上两个答案都为"是", 也应该衡量"安全"与"效率"在特定的环境下谁更重要, 或者说如果因不同步适成的"数据不完整"对用户(或系统)影响不大(或者发生的机率极低), 这种情况也不应该牺牲"效率"而追求同步.

因我没有太多经验, 请大家指正.

banq
2002-12-30 12:53

如果只读就不需同步

有写动作就需要

hxz
2002-12-30 15:00

oracle 等 支持同步!呵呵

jxb8901
2002-12-30 17:23

to banq:
为什么说"有写动作就需要(同步)"? 请看下例:


class T
{ private Object _obj;

public void saveToDb1(Object val)
{
...
//A是线程安全的
A.write(val);
}
public void saveToDb2()
{
...
//A是线程安全的
A.write(this._obj);
}
}

若A.write()已经同步, 那么T.saveToDb2()应该是要同步的,
但T.saveToDb1()需要同步吗? 好象没理由!

banq
2002-12-30 21:15

A虽然是线程安全
但是saveToDb1中不只是A.write(val)一个方法,要其他动作,
如果其他动作没有写同一个资源的操作,saveToDb1就不必是同步的。

这实际是个单线程模式,只允许某个时刻只有一个线程操作某个资源,同时还要防止死锁。死锁是A线程占据1号资源,等待B线程释放2号资源,而B线程正占据2号资源,等待A线程释放1号资源,这就死锁了,这时也需要同步。有写动作需要同步,如果有资源占据容易发生死锁也要同步,后者很难判断,可以使用Borland公司Optimizeit可以动态发现死锁。


jxb8901
2002-12-31 09:43

多谢banq!!!

看来我对"同步"以及"资源"的理解太狭隘了...