我有一些代码如下:
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)
,但仅仅是因为将来我可能需要在类中进行进一步的同步,但使用不同的对象锁。
答案 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实例。