0

次のクラスの動作が非常に悪いです。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

コード:

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();
                    }
                }
            }
    }
});

}
4

3 に答える 3

0

私があなたを正しく理解していれば、スレッドセーフなカウンターが必要です。

その場合は、カウンターをいじるスレッドを同期しようとしないでください。代わりに、それ自体がスレッドセーフなAtomicIntegerを使用してください。synchronizedしたがって、スレッドからステートメントを削除できます。

private static AtomicInteger MY_INT = new AtomicInteger(0);

changelistener では、次を使用します。

int local_value = MY_INT.get();

そしてチェンジメーカーはそうする

System.out.printline( "Incremented to " + MY_INT.incrementAndGet());
于 2013-08-31T09:02:13.620 に答える