java synchronized和reentrantlock不起作用

在操作i++的时候,使用同步方法和锁没有效果

public class aaa implements Runnable {
    static int count = 0;
    public static void main(String[] args) {
        aaa aaa = new aaa();
        aaa.create();
    }
    public void create() {
        ExecutorService executor = Executors.newFixedThreadPool(100);
        for (int i = 0; i < 1000; i++) {
            aaa thread = new aaa();
            executor.execute(thread);
        }
        executor.shutdown();
        while (true){
            if(executor.isTerminated()){
                System.out.println("a " + count);
           break;
            }
        }
    }
    @Override
    public void run() {
        this.test();
    }
    public  synchronized void test() {
            count++;
            System.out.println(count);
        }

}

或者

    public void test() {
        Lock lock = new ReentrantLock(true);
        try {
            lock.lock();
            count++;
            System.out.println(count);
        } finally {
            lock.unlock();
        }

    }

都可能得到错误的结果:

908
907
906
905
904
895
894
890
889
888
887
886
a 998

而使用同步代码块却没有这样的问题:

    public void test() {
        synchronized (aaa.class){
            count++;
            System.out.println(count);
        }
    }

结果:


993
994
995
996
997
998
999
1000
a 1000

我认为以上三种方法应该得到同样的结果,就是最后输出1000,并且count的自增是有顺序的,但是只有最后一种给出了正确的结果。
请问各位哥这个代码问题在哪儿呢?

内存可见性你完全没有考虑到,需要加上volatile关键字,这里涉及到jvm执行线程底层原理。虽然你控制了线程,但是线程之间是不知道这个i有无被修改的,因此需要加上volatile底层会调用CPU指令通知线程i被改了,这样线程就会自旋执行。

总之在count前加上volatile就可以解决问题了,更多知识慢慢研究吧。