Java volatile修饰符实际功能的疑问,大家看看为什么会这样?
本帖最后由 carrd2008 于 2013-05-30 12:51:58 编辑
public class ThreadTest implements Runnable {
String s;
volatile int c;
public ThreadTest(String s) {
this.s = s;
}
public void run() {
for (int i = 0; i < 10; i++) {
c ++;
System.out.println(this.s + ":" + c);
try {
if ("Thread1".equals(s)) {
Thread.sleep(500);
} else {
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Thread(new ThreadTest("Thread1")).start();
new Thread(new ThreadTest("Thread2")).start();
}
以上代码的某一次的执行结果是:
Thread1:1
Thread2:1
Thread1:2
Thread1:3
Thread1:4
Thread1:5
Thread2:2
Thread1:6
Thread1:7
Thread1:8
Thread2:3
Thread1:9
Thread1:10
Thread2:4
Thread2:5
Thread2:6
Thread2:7
Thread2:8
Thread2:9
Thread2:10
从结果看出,Thread1和Thread2这两个线程内部对变量c的运算没有互相影响。
也就是说,每次修改c,都没有跟主存进行同步。
而资料上说:volatile的功能是用于把工作内存中的副本同步到主存中,这样这个线程对变量的修改针对其他线程达到可视的效果。也就是变量共享。
但我的例子中,我用了volatile修饰符,但变量还是没有起到共享的目的。
请问这是为什么?
是我的例子写的有问题吗?
------解决方案--------------------2个线程运行2个不同的实例,内部变量c是不会影响的。
new Thread(new ThreadTest("Thread1")).start();
new Thread(new ThreadTest("Thread2")).start();
要么将
volatile int c;
改成static的
static volatile int c;
要么使用一个实例
package cn.sax.test;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
final ThreadTest t = new ThreadTest("");
new Thread(t, "Thread1").start();
new Thread(t, "Thread2").start();
}
static class ThreadTest implements Runnable {
volatile int c;
public ThreadTest(String s) {
}
public void run() {
final String threadName = Thread.currentThread().getName();
for (int i = 0; i < 10; i++) {