日期:2014-05-20  浏览次数:20690 次

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修饰符,但变量还是没有起到共享的目的。

请问这是为什么?
是我的例子写的有问题吗?
Java 多线程 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++) {