我应该在当前对象实例上还是在数据结构实例上进行同步?

时间:2016-03-11 04:04:29

标签: java multithreading

我有一些代码如下:

rails g migration add_reference_to_events venue:references
rails g migration add_references_to_lineups artist:references event:references

我需要代码是线程安全的,所以我有两个选项,我可以class AddReferenceToEvents < ActiveRecord::Migration def change add_reference :events, :venue, index: true, foreign_key: true end end class AddReferencesToLineups < ActiveRecord::Migration def change add_reference :lineups, :artist, index: true, foreign_key: true add_reference :lineups, :event, index: true, foreign_key: true end end 在这个类的当前实例上,即class MyClass { private Set<Integer> set = new HashSet<>(); public void checkAndAddToSet(Integer i) { if (!set.contains(i)) { set.add(i); } public void checkAndRemove(Integer i) { if (set.contains(i)) { set.remove(i); } } } 或者我可以在{{1}上进行同步实例,即synchronize

这里哪个更好?我倾向于同步数据结构对象synchronized(this),但仅仅是因为将来我可能需要在类中进行进一步的同步,但使用不同的对象锁。

3 个答案:

答案 0 :(得分:0)

只要您不打算在其他地方的其他代码中选择此锁定,您选择哪个显示器锁定无关紧要。

即使我必须在两者之间做出选择,我希望synchronized(this)优先于synchronized(set)。原因是因为我需要检查Hashset代码是否在内部使用任何synchronizied(this)进行任何同步。 所以我可以安全地将synchronized(this)安全地用于我的代码。

答案 1 :(得分:-1)

如果您有其他不依赖于该Set实例的同步方法,则可以使用synchronized(set),否则使用synchronized(this)没有问题。但我建议使用Collections.synchronizedSet,如果你有另一个同步方法则独立使用。

喜欢

Set<Integer> set = new HashSet<>();
Set safeSet = Collections.synchronizedSet(set);

答案 2 :(得分:-2)

取决于。

当您说synchronize(this)或者在方法声明中添加synchronize关键字时 - 它实际上会在用于调用此方法的MyClass实例上进行同步。

但是,如果您在手动编码Set实例上进行同步 - 它将获取与此实例关联的监视器并将其用于同步。

正如您的代码所代表的那样,对于这两种方法都应该没问题;如果您打算使用MyClass作为实用程序类 - 执行putIfAbsent功能,那么您应该同步{{1实例。