我怀疑我的方法是否是线程安全的,相反,我很确定不是线程安全的,但我还没有找到解决方案。 以下是我的代码:
class TestLockSingleton
{
private static TestLockSingleton ourInstance = new TestLockSingleton();
public static TestLockSingleton getInstance() {
return ourInstance;
}
private TestLockSingleton() {
}
...
private Object LockMonitor= new Object();
interface Listener
{
void isEnable(boolean result);
}
public void setStatus(int status){
synchronized(LockMonitor){
this.status = status;
this.setted = true;
}
}
public void isEnable(final Listener listener){
synchronized(LockMonitor){
if(!setted){
LocalBroadcastManager.getInstance(context).registerReceiver( new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
synchronized(LockMonitor){
Bundle bundle = intent.getExtras();
setStatus(bundle.getInt("Status", OFFVALUE));
Listener.isEnable( (status==ACTIVEVALUE)?true:false );
LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
}
}
},new IntentFilter(MYACTION));
}else{
Listener.isEnable((status==ACTIVEVALUE)?true:false );
}
}
}
....
}
现在我的问题是我认为 TestLockSingleton 类中的 isEnable(final Listener Listener) 方法不是 ThreadSafe。
我不想处理多个监听器,而是必须确保最后一个调用方法 isEnable(final Listenerlistener) 的人会收到回调。
但是如果两个不同的线程调用 isEnable(final Listenerlistener) ,最后一个调用该方法的线程将收到两个监听器回调?
编辑:我想用这个推断代码做什么:
- 仅当“状态”变量尚未从 先例调用 isEnable(final Listener Listener),为此,我创建了一个“已设置”变量,并在设置状态变量的同时将其设置为 true。
- 我使用synchronized来防止并发访问“setted”和“status”成员变量
我想完成这个:
线程 A 在 1 次调用时:
TestLockSingleton.getInstance().isEnable( new Listener() { @Override public void isEnable(boolean result) { } })
线程 B 在时间 2 做同样的事情
我希望只有线程 B 接收监听器结果,我会阻止注册多个 BroadcastREceiver,因为如果我这样做,线程 B 会收到两个具有相同结果的回调。
最佳答案
我认为您想要类似下面的代码。
你必须要小心。 Listener.isEnable
将从多个线程调用:调用 TestLockingSingleton.isEnable
的线程和主线程。
public class TestLockSingleton {
// ...
public interface Listener {
void isEnable(boolean isActive);
}
private static TestLockSingleton instance = new TestLockSingleton();
public static TestLockSingleton getInstance() {
return instance;
}
private final Object lock = new Object();
private int status;
private boolean enabled;
private TestLockSingleton() {
}
public void setStatus(int status) {
synchronized (lock) {
this.status = status;
this.enabled = true;
}
}
public void isEnable(Context context, final Listener listener) {
boolean enabled;
boolean active;
synchronized (lock) {
enabled = this.enabled;
active = status == ACTIVEVALUE;
}
if (enabled) {
listener.isEnable(active);
return;
}
LocalBroadcastManager.getInstance(context).registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getExtras().getInt("Status", OFFVALUE);
setStatus(status);
listener.isEnable(status == ACTIVEVALUE);
LocalBroadcastManager.getInstance(context).unregisterReceiver(this);
}
},
new IntentFilter(MYACTION));
}
// ...
}
编辑:以防止 TestLockSingleton.isEnable
在调用 Listener.isEnable
时保持锁定。不清楚在这种情况下这是否是可取的。
关于java - 在对象监视器上同步还是在我的情况下是更好的信号量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39429573/