synchronize()在这里行为很糟糕.可以解决这个问题吗?

nih*_* m. 0 java multithreading synchronization

我有以下课程表现如此糟糕.它由3个线程类组成,序列不正确,也是输出.任何人都知道如何纠正?

输出 -

ANOTHER MY_INT to 1
Got Change for MY_INT : 1
Incrementing MY_INT to 1
Incrementing MY_INT to 2
Got Change for MY_INT : 2
ANOTHER MY_INT to 2
Incrementing MY_INT to 3
ANOTHER MY_INT to 3
Got Change for MY_INT : 3
Incrementing MY_INT to 4
Got Change for MY_INT : 4
ANOTHER MY_INT to 4
Incrementing MY_INT to 5
ANOTHER MY_INT to 5
Got Change for MY_INT : 5
MY_INT:: 5
Run Code Online (Sandbox Code Playgroud)

码:

public class VolatilityTest {

private static int MY_INT = 0;

/**
 * @param args
 * @throws InterruptedException 
 */
public static void main(String[] args) throws InterruptedException {

    VolatilityTest vt = new VolatilityTest();
    vt.changeListener.start();
    vt.changeMaker.start();
    vt.anotherChangeMaker.start();

    /*new VolatilityTest().changeListener.start();
    new VolatilityTest().changeMaker.start();
    new VolatilityTest().anotherChangeMaker.start();*/
}

Thread changeListener = new Thread(new Runnable() {

    @Override
    public void run() {
            synchronized (this) {
                int local_value = MY_INT;
                while (local_value < 5) {
                    if (local_value != MY_INT) {
                        System.out.println("Got Change for MY_INT : "
                                + MY_INT);
                        local_value = MY_INT;
                    }
                }
            }
        }
});

Thread changeMaker = new Thread(new Runnable() {

    @Override
    public void run() {
            synchronized (this) {
                int local_value = MY_INT;
                while (MY_INT < 5) {
                    System.out.println("Incrementing MY_INT to "
                            + (local_value + 1));
                    MY_INT = ++local_value;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
            System.out.println("MY_INT:: "+MY_INT);
    }
});

Thread anotherChangeMaker = new Thread(new Runnable() {

    @Override
    public void run() {
            synchronized (this) {
                int local_value = MY_INT;
                while (MY_INT < 5) {
                    System.out.println("ANOTHER MY_INT to "
                            + (local_value + 1));
                    MY_INT = ++local_value;
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
    }
});

}
Run Code Online (Sandbox Code Playgroud)

SJu*_*n76 9

您正在使用每个线程来同步其关键部分.您必须使用共享对象,否则处于线程的关键部分将不会阻止其他线程进入他们的.

也就是说,在两个不同的线程中

// Thread 1
synchronize(this) {
    pointA
}

// Thread 2
synchronize(this) {
    pointB
}
Run Code Online (Sandbox Code Playgroud)

意味着该程序可以在pointApointB同时进行.

使用共享对象将关键部分彼此锁定.

另外,认为同步关键部分只会阻止同时执行,但不会强制它们按给定顺序执行.

更新:

您需要做什么才能同步添加

// add; any object can be used
private static Object sync_instance = new Object();

// and each synchronized section
synchronized(sync_instance) {...}
Run Code Online (Sandbox Code Playgroud)