获得正确的同步

时间:2015-03-17 19:48:40

标签: java multithreading synchronization runtime-error

我做了一点测试,因为我想存储一个多个线程一次使用的数组(或某种列表)。

我的班级:

package main;

import java.util.Timer;
import java.util.TimerTask;

public class Main {
private final static Object lock = new Object();

public static void main(String[] args) {
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            synchronized (lock) {
                Values.incrementValues();
            }
        }

    }, 1000, 1000);

    Timer timer1 = new Timer();
    timer1.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            synchronized (lock) {
                Values.addValue(0);
            }
        }

    }, 1000, 1000);

    Timer timer2 = new Timer();
    timer2.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            synchronized (lock) {
                Values.printValues();
            }
        }

    }, 1000, 1000);
}
}

这是Class I将数组存储在:     包主;

public class Values {
static int[] values = new int[1];
private final static Object lock = new Object();

public static void incrementValues() {
    synchronized (lock) {
        for (int i = 0; i < values.length; i++) {
            values[i]++;
        }
    }
}

public static void addValue(int e) {
    synchronized (lock) {
        int[] temp = values;
        values = new int[temp.length + 1];
        for (int i = 0; i < temp.length; i++) {
            values[i] = temp[i];
        }
        values[temp.length] = e;
    }
}

public static void printValues() {
    printValues(values);
}

public static void printValues(int[] values) {
    synchronized (lock) {
    }
    StringBuilder sb = new StringBuilder();
    for (int e : values) {
        sb.append(e);
        sb.append(' ');
    }
    System.out.println(sb.toString());
}
}

我应该得到的输出是一排数字,如:10 9 8 7 6 5 4 3 2 1 0

但取而代之的是21 21 19 18 17 16 15 15 14 13 11 10 9 8 7 6 6 5 4 2 1 0

我认为它必须直接在我面前,但我找不到它。

1 个答案:

答案 0 :(得分:0)

您保证两个线程在同步中执行但不保证执行顺序。

因此 incrementValues addValue 将处于竞争状态。您有重复的变量,因为有时会在 incrementValues 之前执行 addValue

如果您想保证连续订单没有任何重复,您应该实现一个门,以确保 incrementValues addValue 以正确的顺序执行。

BTW:我认为Main类中的synchronized块是不必要的,因为你已经在Values类中进行了锁定。