并发 - Java static / non-static synchronized方法同时修改static成员变量,会有问题吗?
本文介绍了并发 - Java static / non-static synchronized方法同时修改static成员变量,会有问题吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
Java里static
和non-static
synchronized方法锁住的分别是对象
和类
,因而是可以同时执行的,那么会存在修改问题吗?搜索没有得到比较关联的答案,来这里问问大家:
示例代码如下:
public class Test {
private static int staticVariableOne = 0;
public synchronized void nonStaticFunction() {
// do some works
staticVariableOne++;
// do some works
}
public synchronized static void staticFunction() {
// do some works
staticVariableOne++;
// do some works
}
}
以上,两个线程分别同时调用nonStaticFunction()和staticFunction(),会出现这种情况(导致一次修改丢失)吗:
1. nonStaticFunction 读 staticVariableOne = 0
2. nonStaticFunction 阻塞
3. staticFunction 读 staticVariableOne = 0
4. staticFunction 写 staticVariableOne = 1
5. nonStaticFunction 继续
6. staticFunction 写 staticVariableOne = 1
解决方案
参考StackOverflow问题:
http://stackoverflow.com/ques...
但是,还是意犹未尽,还请各位多多指教、探讨!
补充:
运行如下测试程序,最后的结果并不是20000,中间有很多次结果都被覆盖了。
public class Test {
private static int staticVariableOne = 0;
public Test() {
super();
}
public static int getStaticVariableOne() {
return staticVariableOne;
}
public static void setStaticVariableOne(int staticVariableOne) {
Test.staticVariableOne = staticVariableOne;
}
private static void increaseStaticVariableOne() {
staticVariableOne++;
}
public synchronized void add() {
System.out.println("执行 add() 开始...");
try {
for (int i = 0; i < 10000; i++) {
increaseStaticVariableOne();
Thread.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行 add() 完毕...");
}
public synchronized static void addStatic() {
System.out.println("执行 addStatic() 开始...");
try {
for (int i = 0; i < 10000; i++) {
increaseStaticVariableOne();
Thread.sleep(2);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行 addStatic() 完毕...");
}
}
public class StudyMain {
public static void main( String[] args ) {
final Test insertData = new Test();
Thread threadOne = new Thread() {
@Override
public void run() {
insertData.add();
}
};
Thread threadTwo = new Thread() {
@Override
public void run() {
Test.addStatic();
}
};
threadOne.start();
threadTwo.start();
try {
threadOne.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
threadTwo.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("After 20000 times increasements, final staticVariableOne is "
+ Test.getStaticVariableOne());
}
}
这篇关于并发 - Java static / non-static synchronized方法同时修改static成员变量,会有问题吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文