Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java监视器和线程并发_Java_Arrays_Multithreading_Concurrency - Fatal编程技术网

Java监视器和线程并发

Java监视器和线程并发,java,arrays,multithreading,concurrency,Java,Arrays,Multithreading,Concurrency,我正在尝试构建简单的多线程应用程序。但我对Java监视器感到困惑。我有许多线程希望将其数据格式化为一个数组。例如,我有超市线程(线程的数据在txt文件中),所以第一个线程有这些产品(牛奶、奶酪、巧克力)和每个产品的国家代码1、2、3 SupermarketA Milk 1 Cheese 2 Chocolate 3 SupermarketB Yogurt 1 Orangle 2 Bannana 3 Tea 7 Kiwi

我正在尝试构建简单的多线程应用程序。但我对Java监视器感到困惑。我有许多线程希望将其数据格式化为一个数组。例如,我有超市线程(线程的数据在txt文件中),所以第一个线程有这些产品(牛奶、奶酪、巧克力)和每个产品的国家代码1、2、3

    SupermarketA
    Milk 1
    Cheese 2
    Chocolate 3
    SupermarketB
    Yogurt 1
    Orangle 2
    Bannana 3
    Tea 7
    Kiwi 9
我想格式化数组,该数组必须包含字段(国家代码和计数) 所以我的数组应该是这样的

Country_code count
1              2
2              2
3              2
7              1
9              1
代码

这是我的监视器课程

 public class SingleArray {
        private SortedArray[] array;
        private int arrayIndex;
        private static final int MAX_SIZE = 5;

    public SingleArray() {
        array = new SortedArray[MAX_SIZE];
        arrayIndex = 0;
        initArray();
    }

    private void initArray() {
        for (int i = 0; i < MAX_SIZE; i++) {
            array[i] = new SortedArray();
        }
    }

    public synchronized void inc(){
        awaitUnderMax();
        notifyAll();
    }

    private void awaitUnderMin(){
        while (arrayIndex == 0) try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void dec(){
        awaitUnderMin();
        notifyAll();
    }

    public void add(ArrayList<Integer> count){
        for (int i = 0; i < count.size(); i++) {
            singleArray.inc();
            int num = count.get(i);
            if (singleArray.arrayIndex == 0) { // if array is empty add value to it
                singleArray.array[0].num = num;
                singleArray.array[0].count++;
                singleArray.arrayIndex++;
            } else {
                if (!isThere(num)) { // if num is a new value to array
                    singleArray.inc();
                    int index1 = singleArray.arrayIndex;
                    if (num > singleArray.array[index1 - 1].num) {
                        singleArray.inc();
                        singleArray.array[index1].num = num;
                        singleArray.inc();
                        singleArray.array[index1].count++;
                        singleArray.inc();
                        singleArray.arrayIndex++;

                        System.out.println(Thread.currentThread().getName() + " first " + singleArray.array[index1].num);
                    } else if (num < singleArray.array[index1 - 1].num) { // jei num mazesne uz paskutinia masyvo reiksme
                        int index = index1 - 1 < 0 ? index1 : index1 - 1;
                        while (index > 0 && num < singleArray.array[index].num) {
                            index--;
                        }
                        if (index != singleArray.arrayIndex) {
                            System.out.println(Thread.currentThread().getName() + " sec " + singleArray.array[index].num);
                            singleArray.array = addPos(singleArray.array, index + 1, num);
                        }
                    }
                }
            }
        }
    }

    public boolean isThere(int number){
        for(int i=0; i<singleArray.arrayIndex; i++){
            singleArray.inc();
            if(number == singleArray.array[i].num){
                singleArray.array[i].count++;
                return true;
            }
        }
        return false;
    }

    private void awaitUnderMax(){
        while (arrayIndex >= MAX_SIZE) try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void removeValue(int number, int howManyItems){
        for(int i=0; i<arrayIndex; i++){
            dec();
            if(number == array[i].num){
                int numberToDelete = array[i].count - howManyItems >= 0 ? howManyItems : array[i].count;
                if(array[i].count >= numberToDelete){
                    array[i].count -= numberToDelete;
                }
                if(array[i].count == 0){
                    deleteItem(i);
                }
            }
            if(array[i].count == 0){
                deleteItem(i);
            }
        }
    }

如何使用java已经提供的并发安全数据集

如果您希望对其进行排序,这一个看起来可能适合您:


只需像在普通集合中那样添加它

我会认为
add
方法应该是同步的?正如您所提到的(这是代码的一部分,我还有其他基于county代码递减数组的线程),我建议将变量arrayIndex和array声明为volatile。
synchronized
方法不能解决您的问题。但是你没有提供足够的信息,所以你可以写一个详细的答案。只有在假设的情况下,才能对代码进行改进,并向您展示实现的方法。请提供更多代码(国家/地区等)。为什么你认为
synchronized
方法可以解决你的问题?你有没有检查过你是否会陷入僵局(我想你应该这样做)?是否可以为您使用另一种数据结构(例如优先级队列/堆)<代码>信号灯可以解决问题,但我们需要更多的代码。花点时间帮助我们理解,我们也会花点时间帮助你解决问题。@Elyasin我认为
synchronized
metod add应该解决我的问题(但我不想这样做)因为一次只有一个线程可以写入数组,所以我也编辑了我的文章
 public class SingleArray {
        private SortedArray[] array;
        private int arrayIndex;
        private static final int MAX_SIZE = 5;

    public SingleArray() {
        array = new SortedArray[MAX_SIZE];
        arrayIndex = 0;
        initArray();
    }

    private void initArray() {
        for (int i = 0; i < MAX_SIZE; i++) {
            array[i] = new SortedArray();
        }
    }

    public synchronized void inc(){
        awaitUnderMax();
        notifyAll();
    }

    private void awaitUnderMin(){
        while (arrayIndex == 0) try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void dec(){
        awaitUnderMin();
        notifyAll();
    }

    public void add(ArrayList<Integer> count){
        for (int i = 0; i < count.size(); i++) {
            singleArray.inc();
            int num = count.get(i);
            if (singleArray.arrayIndex == 0) { // if array is empty add value to it
                singleArray.array[0].num = num;
                singleArray.array[0].count++;
                singleArray.arrayIndex++;
            } else {
                if (!isThere(num)) { // if num is a new value to array
                    singleArray.inc();
                    int index1 = singleArray.arrayIndex;
                    if (num > singleArray.array[index1 - 1].num) {
                        singleArray.inc();
                        singleArray.array[index1].num = num;
                        singleArray.inc();
                        singleArray.array[index1].count++;
                        singleArray.inc();
                        singleArray.arrayIndex++;

                        System.out.println(Thread.currentThread().getName() + " first " + singleArray.array[index1].num);
                    } else if (num < singleArray.array[index1 - 1].num) { // jei num mazesne uz paskutinia masyvo reiksme
                        int index = index1 - 1 < 0 ? index1 : index1 - 1;
                        while (index > 0 && num < singleArray.array[index].num) {
                            index--;
                        }
                        if (index != singleArray.arrayIndex) {
                            System.out.println(Thread.currentThread().getName() + " sec " + singleArray.array[index].num);
                            singleArray.array = addPos(singleArray.array, index + 1, num);
                        }
                    }
                }
            }
        }
    }

    public boolean isThere(int number){
        for(int i=0; i<singleArray.arrayIndex; i++){
            singleArray.inc();
            if(number == singleArray.array[i].num){
                singleArray.array[i].count++;
                return true;
            }
        }
        return false;
    }

    private void awaitUnderMax(){
        while (arrayIndex >= MAX_SIZE) try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void removeValue(int number, int howManyItems){
        for(int i=0; i<arrayIndex; i++){
            dec();
            if(number == array[i].num){
                int numberToDelete = array[i].count - howManyItems >= 0 ? howManyItems : array[i].count;
                if(array[i].count >= numberToDelete){
                    array[i].count -= numberToDelete;
                }
                if(array[i].count == 0){
                    deleteItem(i);
                }
            }
            if(array[i].count == 0){
                deleteItem(i);
            }
        }
    }
 public Thread[] setUpShopsBuilderThreads(){
        int size = data.getSize();
        ArrayList<ArrayList<String>> a = new ArrayList<>();
        ArrayList<ArrayList<Integer>> b = new ArrayList<>();
        ArrayList<ArrayList<Double>> c = new ArrayList<>();
        Thread[] threads = new Thread[size];
        for (int i = 0; i < size; i++) {
            int tmp = data.getIndex(i);
            int range = i + 1 < size ? data.getIndex(i + 1) : data.getWaresSize();
            ArrayList<String> name = new ArrayList<>();
            ArrayList<Integer> count = new ArrayList<>();
            ArrayList<Double> price = new ArrayList<>();
            for (int j = tmp; j < range; j++) {
                name.add(data.getName(j));
                count.add(data.getCount(j));
                price.add(data.getPrice(j));
            }
            a.add(name);
            b.add(count);
            c.add(price);
        }

        procesas_1 p1 = new procesas_1(a.get(0), b.get(0), c.get(0));
        procesas_2 p2 = new procesas_2(a.get(1), b.get(1), c.get(1));
        procesas_3 p3 = new procesas_3(a.get(2), b.get(2), c.get(2));
        procesas_4 p4 = new procesas_4(a.get(3), b.get(3), c.get(3));
        procesas_5 p5 = new procesas_5(a.get(4), b.get(4), c.get(4));

        Thread worker1 = new Thread(p1);
        Thread worker2 = new Thread(p2);
        Thread worker3 = new Thread(p3);
        Thread worker4 = new Thread(p4);
        Thread worker5 = new Thread(p5);

        threads[0] = worker1;
        threads[1] = worker2;
        threads[2] = worker3;
        threads[3] = worker4;
        threads[4] = worker5;

        return threads;
    }

public static void main(String[] args) {
        Starter start = new Starter();
        start.read();
        start.printShopsData();
        start.printUserData();

        Thread[] builderThreads = start.setUpShopsBuilderThreads();

        for(int i=0; i<builderThreads.length; i++){
            builderThreads[i].start();
        }
}