Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
9 / 9 / 3
Регистрация: 03.03.2015
Сообщений: 78

Разделение разбора xml-файла и обработка полученных данных на независимые потоки

17.10.2015, 17:54. Показов 1590. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
файл разбирается при помощи StAX.
разобранные данные записываются в ArrayList. для их обработки они вытаскиваются из этого же ArrayList.
когда разбиваю это на два потока, то в потоке обработки ArrayList существует, но его size равно 0, соответственно никакая обработка данных не происходит.
подскажите куда смотреть, чтоб сделать как надо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.10.2015, 17:54
Ответы с готовыми решениями:

Консольное приложение для периодического опроса XML файла и записи полученных данных в базу SQLlite
Необходимо сделать консольное приложение для периодического опросаXML файла и записи полученных данных в базу SQLlite. Как парсить данные с...

Обработка данных XML-файла
Добрый день! В очередной раз застряла на ерундовом вопросе, надеюсь, что смогу получить у Вас совет. Имеется XML - файл, в котором...

Классы и методы для разбора XML файла
Подскажите какой класс или модуль подключить, какие обьекты создавать/вызывать, функции и методы. Можт ссылки на инфу в Инете кто знает по...

9
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
17.10.2015, 18:11
sskdroid, ArrayList не потокобезопасная коллекция, и скорее всего его нельзя использовать так как это делаете. Попробуйте заменить на какую-нибудь ConcurrentQueue, например на LinkedBlockingQueue.
Больше без кода сложно что-то сказать
1
9 / 9 / 3
Регистрация: 03.03.2015
Сообщений: 78
17.10.2015, 18:44  [ТС]
turbanoff , ну я пробовал с Vector, картина та же самая. есть чувство, что там что-то принципиально не то, нужно добавлять какую-то конструкцию или логику, о которой я в силу неопытности пока не догадываюсь. вот основной код:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class TestTaskThread implements XMLStreamConstants {
    public static void main(String[] args){
     
        new InputThread().start();
        new OutThread().start();
 
    }
 
    private static class InputThread extends Thread{
        public void run(){
            TestTaskThread handler = new TestTaskThread();
            try{
                FileInputStream inStream = new FileInputStream("\\test.xml");
                XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
                int event;
                while (xmlReader.hasNext()) {
                    event = xmlReader.next();
                    switch (event){
                        case START_ELEMENT: handler.processElement(xmlReader); break;
                        case CHARACTERS: handler.processText(xmlReader.getText()); break;
                        case END_ELEMENT: handler.finishElement(xmlReader.getLocalName()); break;
                    }
                }
                xmlReader.close();
            }catch(Exception ex){
                System.out.println("Введите путь к xml-файлу с входными данными, удовлетворяющими xsd-схеме.");
            }
        }
    }
 
    private static class OutThread extends Thread{
        public void run(){
            try{
                for (Figure figure : figures){
                    /*В зависимости от значения figure.getTypeFigure(), которое является названием фигуры,
                    выбирается соответствующий метод для подсчета площади.*/
                    switch (figure.getTypeFigure()){
                        case "triangle": areaTriangle(figure.getArrayValues().get(0), figure.getArrayValues().get(1), figure.getArrayValues().get(2)); break;
                        case "rectangle": areaRectangle(figure.getArrayValues().get(0), figure.getArrayValues().get(1)); break;
                        case "square": areaSquare(figure.getArrayValues().get(0)); break;
                        case "circle": areaCircle(figure.getArrayValues().get(0));
                    }
                    color = figure.getColor();
                    System.out.println(count++ + ": " + color + " - " + (double)Math.round(area*100)/100);
                }
                Thread.sleep(0);
            }catch(InterruptedException ie){System.out.println("Error");}
        }
    }
...
Добавлено через 12 минут
"LinkedBlockingQueue<E> — Блокирующая очередь на связанных нодах, реализованная на «two lock queue» алгоритме: один лок на добавление, другой на вытаскивание элемента."

то есть один поток работает на добавление, второй на вытаскивание и чтоб это работало нужна строгая очередность? и это соответствует определению "независимые потоки"?
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
18.10.2015, 00:50
sskdroid, Очередь нужна просто чтобы разграничить потоки между собой.
Само использование очереди обычно минимально и не вносит задержек: несколько потоков что-нибудь туда быстро кладут, другие несколько потоков быстро вытаскивают и долго обрабатывают. Так что неважно сколько там локов внутри и как она работает.

PS. По вашему коду ничего не понятно. Как потоки между собой общаются? Где ArrayList?
1
9 / 9 / 3
Регистрация: 03.03.2015
Сообщений: 78
18.10.2015, 05:38  [ТС]
вот полностью код.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package ru.ssk.testtask;
 
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
 
/**
 * Created by ssk on 17.10.2015.
 */
 
public class TestTaskThread implements XMLStreamConstants {
    public static void main(String[] args){
        new InputThread().start();
        new OutThread().start();
    }
 
    private static class InputThread extends Thread{
        public void run(){
            TestTaskThread handler = new TestTaskThread();
            try{
                FileInputStream inStream = new FileInputStream("\\test.xml");
                XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(inStream);
                int event;
                while (xmlReader.hasNext()) {
                    event = xmlReader.next();
                    switch (event){
                        case START_ELEMENT: handler.processElement(xmlReader); break;
                        case CHARACTERS: handler.processText(xmlReader.getText()); break;
                        case END_ELEMENT: handler.finishElement(xmlReader.getLocalName()); break;
                    }
                }
                xmlReader.close();
            }catch(Exception ex){
                System.out.println("Введите путь к xml-файлу с входными данными, удовлетворяющими xsd-схеме.");
            }
        }
    }
 
    private static class OutThread extends Thread{
        public void run(){
            try{
                for (Figure figure : figures){
                    /*В зависимости от значения figure.getTypeFigure(), которое является названием фигуры,
                    выбирается соответствующий метод для подсчета площади.*/
                    switch (figure.getTypeFigure()){
                        case "triangle": areaTriangle(figure.getArrayValues().get(0), figure.getArrayValues().get(1), figure.getArrayValues().get(2)); break;
                        case "rectangle": areaRectangle(figure.getArrayValues().get(0), figure.getArrayValues().get(1)); break;
                        case "square": areaSquare(figure.getArrayValues().get(0)); break;
                        case "circle": areaCircle(figure.getArrayValues().get(0));
                    }
                    color = figure.getColor();
                    System.out.println(count++ + ": " + color + " - " + (double)Math.round(area*100)/100);
                }
                Thread.sleep(0);
            }catch(InterruptedException ie){System.out.println("Error");}
        }
    }
 
    static String color;
    private static double area;
    private static int count = 1;
    private boolean inColor, inValue;
    private static Figure figure;
    private static LinkedBlockingQueue<Figure> figures = new LinkedBlockingQueue<>();
 
    private void processElement(XMLStreamReader element) throws XMLStreamException {
        switch (element.getLocalName()){
            case "triangle":
            case "rectangle":
            case "square":
            case "circle": figure = new Figure(); break;
            case "side":
            case "diameter": inValue = true; break;
            case "color": inColor = true;
        }
    }
 
    private void processText(String text){
        if (inColor){
            figure.setColor(text);
            inColor = false;
        }else if (inValue){
            figure.setValue(Double.parseDouble(text));
            inValue = false;
        }
    }
 
    private void finishElement(String name){
        switch (name){
            case "triangle":
                figure.setTypeFigure("triangle");
                addAndNullFigure(); break;
            case "rectangle":
                figure.setTypeFigure("rectangle");
                addAndNullFigure(); break;
            case "square":
                figure.setTypeFigure("square");
                addAndNullFigure(); break;
            case "circle":
                figure.setTypeFigure("circle");
                addAndNullFigure();
        }
    }
 
    private void addAndNullFigure(){
        //Экземпляр класса Figure добавляется в коллекцию figures
        figures.add(figure);
        figure = null;
    }
 
    private static double areaTriangle(double a, double b, double c){
        double p = (a+b+c)/2;
        area = Math.sqrt(p*(p-a)*(p-b)*(p-c));
        return area;
    }
 
    private static double areaRectangle(double a, double b){
        area = a*b;
        return area;
    }
 
    private static double areaSquare(double a){
        area = a*a;
        return area;
    }
 
    private static double areaCircle(double a){
        area = Math.PI*a*a/4;
        return area;
    }
 
    private class Figure{
        private String color;
        private String typeFigure;
        private ArrayList<Double> arrayValues = new ArrayList<>();
 
        public ArrayList<Double> getArrayValues() {return arrayValues;}
        public void setValue(Double text) {arrayValues.add(text);}
 
        public String getColor() {return color;}
        public void setColor(String color) {this.color = color;}
 
        public String getTypeFigure() {return typeFigure;}
        public void setTypeFigure(String typeFigure) {this.typeFigure = typeFigure;}
    }
 
}
потоки никак не общаются между собой. а как они должны общаться? ArrayList заменил на LinkedBlockingQueue, картина та же. то есть начинает работать поток обработки данных, а коллекция с которой он должен работать пустая. или он ее как-то регулярно обновлять что ли должен..
0
 Аватар для ne2win
206 / 206 / 71
Регистрация: 25.02.2014
Сообщений: 569
18.10.2015, 10:16
sskdroid, в методе run() OutThread'a, поставьте безконечный цикл, и извлекайте элементы, методами которые для этого предназначены, а не форичем
1
9 / 9 / 3
Регистрация: 03.03.2015
Сообщений: 78
19.10.2015, 15:17  [ТС]
да, LinkedBlockingQueue, бесконечный цикл, метод take() - вытащить и удалить первый элемент, и все работает)
теперь я пытаюсь придумать как сделать без бесконечного цикла, а то не дело, когда поток висит такой.
как я понимаю, останавливать цикл, если size() коллекции = 0 не пойдет, поскольку поток на вытаскивание может опередить поток, который кладет элементы?

или не может опередить, если поток который кладет запускается раньше? тестирую на большом файле, когда начинает работать поток на Out в коллекции уже 300 элементов
0
 Аватар для ne2win
206 / 206 / 71
Регистрация: 25.02.2014
Сообщений: 569
19.10.2015, 15:45
sskdroid, условием выхода должно быть то, что коллекция пустая и первый поток завершен
1
9 / 9 / 3
Регистрация: 03.03.2015
Сообщений: 78
19.10.2015, 16:15  [ТС]
Kochmarik, действительно, очевидно.
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
19.10.2015, 18:23
sskdroid, Есть еще популярная техника (Poison Pill), чтобы остановить Consumer-ов очереди - добавлять в конце обработки элемент-маркер конца очереди.
А в потоке, который читает из очереди, проверять то, что он достал.
В вашем случае, например, можно добавлять Figure с typeFigure = null.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.10.2015, 18:23
Помогаю со студенческими работами здесь

Обработка полученных данных.
Я сделал сервер на чистых WinSock1. Потом принимаю данные. char str; err = recv(s1, str, sizeof(str), 0 ); Есть пару вопросов. ...

Обработка полученных данных с COM порта
Доброго всем времени суток. Вопрос такого плана - есть некое устройство посылающее данные в COM порт. Нужно на первом этапе ловить эти...

Vk api обработка полученных данных
Доброе время суток Дорогие знатоки подскажите пожалуйста как можно обработать данные полученные после запроса дело в том что хотел...

Обработка данных, полученных из COM-порта
В текстовом файле одна строка с данными полученными из СОМ порта(файл REG.jpg). Ее надо обработать, конкретно получить цифровые значения...

Обработка данных полученных из SerialPort
Добрый день. подскажите пожалуйста как решить следующую задачу? На VB.NET в ком порт нужно отправить 100 разных команд. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru