在这里,我编写了有关本地,成员,易失成员的访问速度的测试:
public class VolatileTest {
public int member = -100;
public volatile int volatileMember = -100;
public static void main(String[] args) {
int testloop = 10;
for (int i = 1; i <= testloop; i++) {
System.out.println("Round:" + i);
VolatileTest vt = new VolatileTest();
vt.runTest();
System.out.println();
}
}
public void runTest() {
int local = -100;
int loop = 1;
int loop2 = Integer.MAX_VALUE;
long startTime;
startTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
for (int j = 0; j < loop2; j++) {
}
for (int j = 0; j < loop2; j++) {
}
}
System.out.println("Empty:" + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
for (int j = 0; j < loop2; j++) {
local++;
}
for (int j = 0; j < loop2; j++) {
local--;
}
}
System.out.println("Local:" + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
for (int j = 0; j < loop2; j++) {
member++;
}
for (int j = 0; j < loop2; j++) {
member--;
}
}
System.out.println("Member:" + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
for (int j = 0; j < loop2; j++) {
volatileMember++;
}
for (int j = 0; j < loop2; j++) {
volatileMember--;
}
}
System.out.println("VMember:" + (System.currentTimeMillis() - startTime));
}
}
这是我的X220(I5 CPU)上的结果:
回合:1 空:5本地:10成员:312 VM会员:33378
回合:2 空:31本地:0成员:294 VM会员:33180
回合:3 空:0本地:0成员:306 VM会员:33085
回合:4 空:0本地:0成员:300 VM会员:33066
回合:5 空:0本地:0成员:303 VMember:33078
回合:6 空:0本地:0成员:299 VMember:33398
回合:7 空:0本地:0成员:305 VMember:33139
回合:8 空:0本地:0成员:307 VM会员:33490
回合:9 空:0本地:0成员:350 VM会员:35291
回合:10 空:0本地:0成员:332 VM会员:33838
令我惊讶的是,访问易失性成员的速度比普通成员慢100倍。我知道关于volatile成员有一些突出的功能,例如对它的修改将立即对所有线程可见,对volatile变量的访问点起着“内存屏障”的作用。但是所有这些副作用是否可能是慢100倍的主要原因?
PS:我还在Core II CPU机器上进行了测试。它大约是9:50,大约慢5倍。似乎这也与CPU架构有关。5倍还大吧?
我假设在每次调用时都必须检查其变量是否初始化,因此将比慢,这样做对吗?
问题内容: 如果在一个类中我有一个ConcurrentHashMap实例,该实例将被多个线程修改并读取,则可以这样定义: 添加到myMap字段会导致错误,提示我只能使用final或volatile。为什么不能两者兼而有之? 问题答案: 仅与变量本身的修改有关,与变量所指的对象无关。有一个字段是没有意义的,因为不能修改最终字段。只需声明该字段,就可以了。
我有一个表,其中有(其他20个)列、和,以及和的索引。该表有大约500k行。 为什么以下to查询在速度上差异如此之大?查询A需要0.3秒,而查询B需要28秒。 查询A 我使用MySQL5.1.34。
通过下列任意一个方法访问成员变量时将返回 Field 类型的对象或数组。 getFields() getField(String name) getDeclaredFields() getDeclaredField(String name) 上述方法返回的 Field 对象代表一个成员变量。例如,要访问一个名称为 price 的成员变量,示例代码如下: Field 类的常用方法如表 1 所示 表1
最近在review代码的时候发现,使用了空指针调用成员函数,并且成员函数内部有使用到成员变量,居然没有出错。很是奇怪,就用一篇博客把关于空指针调用成员函数相关的内容总结起来。 空指针调用成员函数 调用普通成员函数 如果空指针调用普通成员函数,看该函数体中是否使用到了this指针(是否访问非静态成员变量)。如果使用到了this指针,程序会崩溃;如果没有使用到this指针,程序不会崩溃。当然,如果访问
来自Javadocs 使用易失性变量降低了内存一致性错误的风险,因为对易失性变量的任何写入都与同一变量的后续读取建立了先发生后发生的关系。这意味着对易失性变量的更改始终对其他线程可见。 如果对volatile变量所做的更改对任何其他线程都是可见的,那么为什么在多个线程写入该变量的情况下不能使用volatile变量呢。为什么volatile只用于一个线程正在写入或读取该变量,而另一个线程只读取该变量