java 中的同步方法未按预期工作

Synchronized method in java does not work as indended

我想学习如何使用java中的synchronized方法,实现了下面的代码

public class checkThread {
    volatile int i = 0;
    
    public void increment() {
        i++;
    }
}
public class TestSync extends checkThread{
    public static void main(String[] args) {
        checkThread ct1 = new checkThread();
        Object iLock = new Object();
        for(int i = 0 ; i < 10 ; i++) {
            extracted(ct1, iLock);      
        }
    }    
    private static void extracted(checkThread ct1, Object iLock) {
        synchronized (iLock) {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int a = 0; a < 1000; a++) {
                        ct1.increment();
                    }
                }
            });
            t1.start();
        }
        synchronized (iLock) {
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int a = 0; a < 1000; a++) {
                        ct1.increment();
                    }
                }
            });
            t2.start();
        }
        synchronized (iLock) {
            System.out.println(ct1.i);
        }
    }
}

但是我得到的输出根本不同步!

1000 2000 4000 6000 8000 9000 11575 13575 15575 17459

为什么我得到的是这样的输出,而不是我想要的 1000 的倍数?

如果您试图确保 run() 方法将由一个线程在另一个线程开始之前完成;那么你需要同步运行方法里面的内容,而不是线程创建部分。

在你的具体例子中,你需要有一个可以被两个线程访问的对象,然后获取该对象的锁。

让我通过更改您的代码在下面添加一个示例;但这可能不是最好的方法;只是想解释一下。

checkThread iLock = new checkThread();

public void someMethod() {

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (iLock) {            
                for(int a = 0; a < 1000; a++) {
                    ct1.increment();
                }
            }
        });
        t1.start();
    }

    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            synchronized (iLock) {            
                for(int a = 0; a < 1000; a++) {
                    ct1.increment();
                }
            }
        });
        t2.start();
    }
    
    synchronized (iLock) {
        System.out.println(ct1.i);
    }
}