关于Java同步块的3个快速问题
据我所知,下面的代码,在synchronized块中,这是一个计数器的实例.
问题1:在下面的示例中,这是否意味着当线程A到达同步块时,线程B被阻止对计数器的实例做任何事情?换句话说,这是否意味着线程可以继续按照他们的意愿执行,但是当到达同步块时,另一个停止对类执行任何操作,直到块退出? public class Counter { public void increment() { // Some code synchronized (this) { // <---- "this" is an instance of Counter // Some more code } } } 比较上面的代码 public class Counter { List<String> listOfStrings = new ArrayList<String>(); public void increment() { // Some code synchronized (listOfStrings) { // Some code that deals with // listOfStrings } } } 问题2:在上面的示例中,一旦线程A到达同步块,线程B可以继续读取和写入类中的任何内容,但listOfStrings ArrayList除外,它是同步块中的互斥锁.它是否正确? 问题3:如果我们需要对多个对象进行修改,这是我们应该使用的互斥体,这是否更为正确? 例如: public class Counter { List<String> listOfStrings = new ArrayList<String>(); List<Integers> listOfIntegers = new ArrayList<Integers>(); public void increment() { // Some code synchronized (this) { // Some code that deals with // listOfStrings and listOfIntegers } } } 我理解正确吗?如果我错误的话,请更正. 解决方法
不,线程B被阻止进入同步的代码块,它仍然可以输入其他方法:那些未同步的方法和使用不同对象同步的方法.线程B不仅可以访问使用已由不同线程占用的对象同步的块(同步锁是可重入的).
事实并非如此,listOfStrings在一个同步块中用作互斥锁这一事实并不意味着其他线程无法显式访问该对象.它只表示其他线程无法访问由同一对象保护的同步块.因此,如果要保护对listOfStrings对象的访问,则必须同步访问该对象的所有方法并使用相同的锁(例如listOfStrings). BTW您同步的每个对象都应该是最终的,以避免头痛.
是的,不是.考虑以下情况: List<String> listOfStrings = new ArrayList<String>(); List<Integers> listOfIntegers = new ArrayList<Integers>(); Set<String> setOfStrings = new HashSet<String>(); Set<Integers> setOfIntegers = new HashSet<Integers>(); 如果一个方法只访问列表而第二个方法只访问集合,则可以安全地使用两个锁 – 一个用于第一个方法,第二个用于第二个方法.同步这一点不会有害,但会影响性能: private final Object listLock = new Object(); private final Object setLock = new Object(); 然后: synchronized (listLock) { // Some code that deals with // setOfStrings and setOfIntegers } //... synchronized (setLock) { // Some code that deals with // setOfStrings and setOfIntegers } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |