我的FileManager
公开了一个write
方法,其中包含一个synchronized块以防止出现并发问题:
class FileManager{
Object lock = new Object();
public void write() {
synchronized (lock) {
String id = nextId();
write(id);
}
}
}
但是,如果存在多个FileManager
实例,则它们的写入方法仍然可以同时执行。将FileManager作为单例是否可以很好地解决这个可能的并发问题?或者我应该以其他方式使用syncrhonized
关键字吗?
答案 0 :(得分:2)
有几种方法可以做到:
static Object lock = new Object();
,这样您将始终锁定类级锁定对象。public static synchronized void write() {
,这样再次使用类级锁定对象,但不同的是,这次你将使用{{1的类级别锁定而不是你的锁对象。其他一些要考虑的要点:
FileManager
,并且所有静态+同步方法都必须等到该客户端已释放锁定,现在如果该客户端正在进行某些密集操作那就是性能损失。synchronized(FileManager.class){
),那么需要注意的一件事是将其设为private static final Object lock = new Object();
,否则它仍然会暴露您的锁定。否则它不会受到我上面提到的问题的困扰。但只有这种方法的另一个原因是 - (1)你不能在方法级别使用它,你通过在private
块中包含代码块在方法中使用此锁。 (2.)如果假设您的API的客户端想要与使用此锁的某些同步方法同步,那么他们不能。但是还有更深层次的东西,现在通常这就是锁定发生的方式。选择最符合您要求的产品。
在一般注释中,使用synchronized
或synchronized
进行锁定是旧的锁定方式,使用Java提供的新并发API,您应该使用ReentrantLock和{{}等API {3}}用于实现同步机制。
答案 1 :(得分:0)
是否使用单例模式取决于各个FileManager
实例是否具有自己的状态。如果所有实例基本上共享相同的状态然后是,那么单例模式在这里将是一个不错的选择。另一方面,如果它们可以具有不同的状态,但是您仍然需要跨实例同步方法访问,那么您可以在静态类成员上进行同步,例如:
class FileManager {
static final Object lock = new Object();
public void write() {
synchronized (lock) {
...
}
}
}
答案 2 :(得分:0)
However, if multiple instances of FileManager exist, their write methods can still be executed concurrently?
Yes. They can run in parallel since lock exists at instance level i.e at object level and not at class level.
Would making FileManager a singleton be a good fix to this possible concurrency issue?
No. Making a class singleton if it had synchronized
blocks is not necessary. But if you really need only instance of FileManager
as per your design, they you can go for Singleton with static
lock.
should I use syncrhonized keyword in another way?
You can use Lock and ReentrantLock as other alternatives.
Refer to below posts for more details:
What does 'synchronized' mean?