这可能是一个简单的问题,但对我来说仍然是一个问题。我有一个类有task
的方法,我想确保这个类只有一个实例可以在time.I已经像这样实现了,我正在以正确的方式做到吗?
class A{
public void task(){
synchronized(A.this){
//method stuff
}
}
}
class B{
public static void main(String a[]){
new A().task();
}
}
class C{
public static void main(String a[]){
new A().task();
}
}
如果B
启动task
并且在C
完成之前C
也开始执行任务,我希望B
等到{{1}}完成。
到目前为止似乎有效。但我想知道这是正确的方法,
答案 0 :(得分:3)
不完全。正如您所知,您保证一次只有一个线程在给定实例上执行task()
- 但是单独的实例仍然可以同时运行task()
。也就是说,如果你这样做(伪代码):
Thread t1 = new A().task();
Thread t2 = new A().task();
t1.start();
t2.start();
然后,由于每个线程都创建了一个单独的A
实例,因此每个线程都可以同时运行task()
。
您需要在static
字段(或A.class
)上进行同步,或使task()
成为静态的同步方法(在这种情况下synchronized
会根据Class
对象)。
答案 1 :(得分:2)
synchronized(A.this)将依赖于你的A实例。
在您的情况下,该实例可能不同,即运行B.main()的线程和另一个运行C.main()的线程将创建一个不同的A实例。因此,其中一个将能够访问public void task()
即使它已经被另一个人访问了。
如果您只想确保一次一个线程可以访问该任务方法,您可以这样做:
class A{
private static final Object myLock = new Object ();
public void task() {
synchronized(myLock) {
//method stuff
}
}
}
您还可以查看Locks。