【发布时间】:2022-06-13 15:21:09
【问题描述】:
当一个变量被多个并发线程读/写时,需要volatile修饰符。
是否有工具可以自动检测缺少的volatile 修饰符,例如在 Android Studio 中?
算法:
for (Class c:allClasses) {
for (Field f:allFields) {
List<Method> allMethods = getCallHierarchy(field);
for (Method m:allMethods) {
List<Thread> threads = getCallingThreads();
if (threads.size() > 1) {
Log.w("Warning: field "+f+" is accessed by several threads.");
}
}
}
}
算法测试代码:
public class Foo {
private int a; //accessed by only one Thread - ok
private int b; //accessed by two Threads - show compiler warning
public static void main(String[] args) {
a = 10; //no race condition - ok
b = 1;
Thread th = new Thread(this::someMethod);
th.start(); //update to field "b" might stay unnoticed for mainThread
while(!isDone) {
Thread.sleep(20); //wait for the other Thread to finish
}
b += 2;
System.out.println(b); //3 or 6
}
private void someMethod() {
b += 3;
isDone = true;
}
private volatile boolean isDone = false;
}
【问题讨论】:
-
这似乎需要完整的流分析来确定 (a) 哪些方法是从哪些对象上的哪些线程调用的,以及 (b) 是否使用了任何其他同步。而且由于线程是一种运行时现象,即使那样它也不能是完整的。
-
我的意思是,如果您使用其他形式的锁定,则不需要它,根据您需要的确切并发语义,它是不够的,因此这样的标志可能会给用户一种非常错误的安全感。
标签: java android-studio volatile