给出一个c++类foo,里面有一个同步方法。我们有两个foo的对象,称为f1和f2,如果f1和f2并发运行,我们能保证同步方法只被一个线程访问吗?
我的想法:
使用互斥锁,谁需要访问这个方法,谁就获得互斥锁。
这个面试问题似乎不那么简单。有解决方案吗?
谢谢
在java中,除非方法是静态的,否则您需要在外部同步,以确保该方法一次只能由一个线程调用。
还可以在类的静态变量上同步方法本身。例如
public class myClass
{
private static Object myLock = new Object();
public void myMethod()
{
synchronized(myLock)
{
// ...
}
}
}
使用静态方法,您可以在Java中执行以下操作:
class Foo {
public static synchronized void mymethod() {
...
}
}
在本例中,您实际上在Foo.class
上同步。
如果你有一个实例方法(即非静态),你需要同步,你可以在方法中放入一个synchronized
块,在任何对象上同步,甚至在类本身上同步:
public void mymethod() {
synchronized( Foo.class ) {
...
}
}
注意,这将同步访问同一类中的其他静态同步方法du到共享锁对象Foo.class
。
顺便说一下,这个问题的答案取决于访问的定义:多个线程可以访问方法,通过尝试调用它,读取它的反射元数据,甚至在嵌套同步块的情况下进入它,但它们通常不会并发执行它,除非方法的部分未同步(或同步在不同的锁对象上)。
如果我没理解错,你想让它在所有实例中同步,那么就让方法静态同步
如果您有两个不同的foo
类实例,那么发生什么都没关系,因为每个实例都有不同的方法副本,并且同步发生在this
对象上:
public synchronized void method() {
// code
}
等价于:
public void method() {
synchronized(this) {
// code
}
}
话虽如此,如果每个线程从foo
的不同实例调用method
:
- 他们将获得不同的锁
- 如果你不修改
foo
类之外的数据,它们将不会产生任何数据竞争。