Paw*_*wel 0 java volatile android-studio
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.");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
测试算法的代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
不,不可能。
volatile当多个并发线程读/写变量时需要修饰符。
这是完全错误的。
任何由多个线程访问的字段(至少有一个正在写入)都需要“发生前”保护。
volatile只是获取它的一种方法。synchronized是另一个。还有更奇特的方式。
哪个代码执行此操作?这……无法说清楚。在编译时不可能知道哪一行代码可能在哪个线程下运行。线程模型的设置方式以及暂停问题本身,这在数学上是不可能做到的。
这仅留下一条路线:
拥有一个虚拟机,对整个系统中每个非易失性字段的每次写入进行簿记,标记当时哪些锁处于活动状态、粗略的时间戳和堆栈跟踪。
这是一个令人难以置信的记账量,即使是在拥有大量内存的强大手机上,这也会让速度变得缓慢。但是,让我们这样做吧,并要求开发人员或测试人员在使用手机上的每个功能时耐心等待。
系统运行很长一段时间后,会发现字段访问在时间上似乎是交错的,并且没有共享活动锁。吐出这些访问:瞧,有一个列表,开发人员需要检查正在发生的情况,并可能添加某种锁定机制。可能是“标记字段volatile”,但更有可能的是您应该做其他事情来确保正确控制并发访问;volatile有点松散,大多数并发原则都不能用volatile字段正确编写。
我不知道有任何这样的工具,但至少现在你知道具体要寻找什么。
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |