Главная страница
Навигация по странице:

  • 7.3. Конструирование отчета

  • 7.4. Формирование отчета из Java-приложения

  • 7.5. Порядок выполнения лабораторной работы

  • 7.6. Содержание отчета

  • Лабораторная работа № 8. Организация многопоточных приложений

  • 8.1. Понятие многопоточного программирования

  • 8.2. Создание потока

  • 8.3. Синхронизация потоков

  • 8.4. Взаимодействие потоков

  • БЖД методичка. Метод указания лаб - последняя редакция (1). Методические указания к лабораторным работам СанктПетербург Издательство спбгэту лэти 2013


    Скачать 1.15 Mb.
    НазваниеМетодические указания к лабораторным работам СанктПетербург Издательство спбгэту лэти 2013
    АнкорБЖД методичка
    Дата06.09.2021
    Размер1.15 Mb.
    Формат файлаpdf
    Имя файлаМетод указания лаб - последняя редакция (1).pdf
    ТипМетодические указания
    #229976
    страница4 из 6
    1   2   3   4   5   6
    7.2. Создание файла шаблона отчета по структуре XML-файла
    Чтобы сгенерировать отчет, необходимо сформировать XML-файл c разметкой отчета. Для этого надо выполнить следующие действия: а) нажать кнопку «Report Datasources» на панели инструментов главно- го окна iReport Designer; б) нажать в открывшемся диалоговом окне кнопку «New»; в) выбрать из всех возможных вариантов шаблонов «XML file datasource»; г) используя кнопку «Browse», указать, где находится XML-файл, структура которого будет использоваться как эталон для конструирования отчета;

    39 д) задать имя шаблона и проверить с помощью кнопки «Test» наличие связи шаблона с XML-файлом, затем нажать «Save», чтобы сохранить его; е) нажать кнопку «Close», предварительно убедившись, что созданный шаблон отображается в списке источников; ж) войти в пункт меню «File → New», выбрать интересующий вид шаблона отчета (например, Simple Blue) и нажать кнопку «Open this
    Template»; з) указать в открывшемся окне имя отчета и место его сохранения
    (рекомендуется в качестве места хранения файла отчета указать папку Java- проекта), затем нажать кнопки «Next» и «Finish».
    По результатам всех выполненных действий в папке проекта появится файл шаблона отчета с раширением jrxml. На этом этапе он будет содержать только скелет шаблона.
    7.3. Конструирование отчета
    Конструирование отчета начинается с включения в шаблон полей дан- ных, которые требуется отобразить в отчете. Для этого необходимо нажать кнопку «Report Query» в области построения отчета. Откроется диалоговое окно, в котором необходимо выполнить следующие действия: а) выбрать в выпадающем списке «Query language» язык запросов к
    XML-файлам «XPath» (справа в диалоговом окне отобразится дерево XML- файла с данными для отчета); б) указать в окне запросов, к каким узлам дерева необходим доступ
    (отмеченные узлы в дереве будут выделены жирным шрифтом); в) перетащить в нижнее окно с использованием механизма drag-and- drop элементы дерева, значения которых требуется отобразить в отчете; г) нажать кнопку «ОК» для завершения настройки шаблона на выборку данных из XML-файла.
    На рис. 7.1 приведено диалоговое окно, в котором выполнена настрой- ка шаблона для следующего XML-файла:






    40
    Рис. 7.1. Диалоговое окно настройки запросов к данным
    Настройка расположения элементов в отчете осуществляется перетас- киванием (drag-and-drop) их из узла Fields окна Report Inspector в поля De- tailField области построения отчета, при этом в поле DetailField будет ото- бражаться значение элемента, а в поле Label

    название элемента. Это назва- ние, как и другие надписи шаблона, можно заменить на нужный текст. На рис. 7.2 показано, как выглядит форма шаблона после настройки расположе- ния элементов и добавления в нее надписей.
    Рис. 7.2. Форма шаблона после размещения элементов

    41
    Внешний вид сконструированного отчета с отображением данных из
    XML-файла можно вывести на экран нажатием кнопки «Preview». На рис. 7.3 показан внешний вид отчета, сгенерированного по приведенному ранее шаблону.
    Рис. 7.3. Представление отчета на экране
    Для изменения внешнего вида отчета необходимо отредактировать шаблон и повторить все описанные ранее процедуры.
    7.4. Формирование отчета из Java-приложения
    Разработанный и проверенный в дизайнере iReport шаблон отчета можно использовать в Java-приложении для построения отчетов по данным, хранящимся в XML-файлах, структура которых совпадает со структурой
    XML-файла, заданного в качестве эталона при конструировании шаблона от- чета. Для этого надо подключить библиотеки дизайнера iReport к проекту приложения. Это можно сделать в среде Eclipse вручную, скопировав jar- файлы из каталога \Jaspersoft\iReport-5.0.0\ireport\modules\ext в каталог про- екта (затем нажать клавишу F5), или использовать пункт меню Build Path →
    Configure Build Path. В открывшемся окне выбрать вкладку Libraries и нажать кнопку Add External JARs, после чего в диалоговом окне указать, в каком ка- талоге находятся файлы библиотеки. Если шаблон отчета (jrxml-файл) не был сохранен в проекте при его создании в дизайнере iReport, то его необхо- димо переписать в каталог проекта.
    Используя классы библиотеки JasperReports можно написать метод, который будет формировать отчет в PDF- или HTML-формате. В этом методе нужно реализовать следующие операции: а) создание объекта класса JRDataSource для доступа к XML-файлу, где хранятся данные для отчета;

    42 б) создание XML-отчета на базе шаблона jrxml (метод
    JasperCompileManager.compileReport); в) включение данных в XML-отчет (метод JasperFillManager.fillReport); г) генерация шаблона отчета в формате PDF или HTML (объекты клас- са JRPdfExporter или JRHtmlExporter); д) задание имени файла для выгрузки отчета
    (параметр
    JRExporterParameter.OUTPUT_FILE_NAME); е) подключение данных к шаблону отчета
    (параметр
    JRExporterParameter.JASPER_PRINT); ж) выгрузка отчета в файл в заданном формате (метод exportReport).
    Вариант описания такого метода выглядит следующим образом: public static void print(String datasource, String xpath, String template, String resultpath)
    { try {
    // Указание источника XML-данных
    JRDataSource ds = new JRXmlDataSource(datasource, xpath);
    // Создание отчета на базе шаблона
    JasperReport jasperReport = JasperCompileManager.compileReport(template);
    // Заполнение отчета данными
    JasperPrint print = JasperFillManager.fillReport(jasperReport, new HashMap(), ds);
    JRExporter exporter = null; if(resultpath.toLowerCase().endswith("pdf")) exporter = new JRPdfExporter(); // Генерация отчета в формате PDF else exporter = new JRHtmlExporter (); // Генерация отчета в формате HTML
    // Задание имени файла для выгрузки отчета exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, resultpath);
    // Подключение данных к отчету exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
    // Выгрузка отчета в заданном формате exporter.exportReport();
    } catch (JRException e) { e.printStackTrace(); }
    }
    Данный метод использует следующие входные параметры:

    datasource – имя XML-файла с данными;

    xpath – «XPath» (тип источника данных – XML-файл);

    template – имя jrxml-файла шаблона;

    resultpath – имя файла отчета.

    43
    7.5. Порядок выполнения лабораторной работы
    1. Разработайте с помощью дизайнера iReport 2 варианта шаблона отчета для XML-файла, созданного в лабораторной работе № 6. Шаблоны должны отличаться дизайном и расположением данных. Снимите скриншоты, иллюстрирующие процесс построения шаблона.
    2. Создайте новый проект, который будет дублировать проект лабораторной работы № 6, и добавьте в него необходимые библиотеки из дизайнера iReport.
    3. Разработайте и включите в проект метод построения отчета в PDF- формате для первого варианта шаблона и в HTML-формате

    для второго.
    4. Запустите приложение и после его завершения просмотрите правильность сгенерированных PDF- и HTML-файлов. Распечатайте полученные файлы.
    5. Сгенерируйте документацию с помощью Javadoc и просмотрите ее в браузере.
    7.6. Содержание отчета
    Отчет по лабораторной работе должен содержать:
    1. Распечатку исходного XML-файла.
    2. Скриншоты, иллюстрирующие построение шаблона в дизайнере iReport.
    3. Распечатку сгенерированных файлов.
    4. Текст документации, сгенерированный Javadoc.
    5. Исходный текст метода построения отчета.
    Лабораторная работа № 8. Организация многопоточных
    приложений
    Цель работы: знакомство с правилами и классами построения парал- лельных приложений в языке Java.
    8.1. Понятие многопоточного программирования
    Многопоточность – это реализация параллелизма в приложении на ос- нове выполняющихся потоков. Поток выполнения thread(иногда их называ- ют подпроцессами или нитями процесса) является частью кода приложения, выполняемой последовательно. В отличие от многозадачности, где задачи используют собственное адресное пространство, потоки приложения исполь- зуют одно адресное пространство и разделяют процессорное время. Они вы-

    44 полняются асинхронно, совместно используя сегменты данных и кода при- ложения.
    Java обеспечивает встроенную поддержку многопоточного программи- рования. Когда Java-приложение запускается на выполнение, то автоматиче- ски создается один поток, называемый главным (main thread), так как это единственный поток, выполняющийся при запуске программы. Главный по- ток вызывает метод main(), обеспечивающий основную логику его выполне- ния. Когда главный поток останавливается, приложение завершается. Для за- пуска новых потоков внутри приложения программист должен их самостоя- тельно создать.
    8.2. Создание потока
    Многопоточная система Java построена на классе Thread, его методах и связанном с ним интерфейсе Runnable, определенных в пакетах java.lang.Thread и java.lang.Runnable. Чтобы создать новый поток, необходи- мо или расширить класс Thread, или реализовать интерфейс Runnable. Пер- вый способ базируется на построении нового класса, который будет расши- рять класс Thread, и на замене в нем метода run(), являющегося точкой входа для нового потока. Экземпляр потока может быть создан с помощью конст- рукторов Thread() – без указания имени потока или Thread(String name) – с указанием имени потока.
    Для запуска созданного зкземпляра потока нужно в приложении вы- звать метод start(), который в свою очередь вызовет метод run(). Кроме мето- да start() класс Thread предоставляет другие операции, позволяющие управ- лять потоками:

    final void stop()

    заканчивает выполнение потока;

    static void sleep(long msec)

    прекращает выполнение потока на ука- занное количество миллисекунд;

    static void yield()

    заставляет поток передать управление другому потоку;

    final void suspend()

    приостанавливает выполнение потока;

    final void resume()

    возобновляет выполнение потока;

    final String GetName()

    определяет имя потока;

    final void setName(String threadName) – устанавливает новое имя по- тока;

    void setPriority(int newPriority ) – устанавливает приоритет потока;

    45

    int GetPriority () – определяет приоритет потока;

    boolean IsAlive()

    определяет, выполняется поток или нет;

    void Join()

    ожидает завершения потока;

    void join(long millis) – ожидает завершения потока в течение заданно- го в миллисекундах времени;

    static Thread currentThread() – определяет текущий работающий по- ток.
    Наследование от Thread делает его единственным родителем класса, что не всегда удобно, поэтому потоки часто создаются с помощью интерфей- са Runnable. Реализация потока через интерфейс Runnable заключается в оп- ределении класса, который наследует данный интерфейс. Это позволяет за- пустить выполнение объекта данного класса в отдельном потоке. Для этого в классе нужно описать конструктор и метод с именем run (). В переопреде- ляемом методе run () задается алгоритм работы потока. Конструктор должен породить объект класса Thread и запустить его с помощью метода start(). Для порождения объекта Thread могут использоваться следующие типы конст- рукторов:

    Thread(Runnable target)

    с указанием объекта, для которого будет вызываться метод run;

    Thread(Runnable target, String name)

    с указанием объекта, для кото- рого будет вызываться метод run, а также имени потока.
    При использовании наследования класса Thread объект, представляю- щий сам поток выполнения, и объект с методом run(), реализующим необхо- димую функциональность, были объединены в одном экземпляре класса, в то время как при использовании интерфейса Runnable они разделены. Какой из двух подходов удобней, решается в каждом конкретном случае.
    Один экземпляр класса с интерфейсом Runnable можно передать не- скольким объектам Thread. Это означает, что несколько потоков будут па- раллельно делать одну и ту же работу. Если приложение создало несколько потоков, то все они выполняются параллельно, причем время центрального процессора (или нескольких центральных процессоров в мультипроцессор- ных системах) распределяется между этими потоками. Диспетчеризация или планирование потоков осуществляется на основе приоритетов. Приложения
    Java могут задавать значение приоритета потока. Для этого можно пользо- ваться методом setPriority
    (int newPriority) с константами

    46
    NORM_PRIORITY=5, MAX_PRIORITY=10 и MIN_PRIORITY=1 или указать целое положительное число от 1 до 10.
    По умолчанию вновь созданный поток имеет приоритет
    NORM_PRIORITY. Если потоки в системе имеют одинаковый приоритет, то все потоки пользуются процессорным временем на равных правах. Потоки с повышенным приоритетом выполняются в первую очередь, а с пониженным

    только при отсутствии готовых к выполнению потоков, имеющих более высокий приоритет.
    8.3. Синхронизация потоков
    Синхронизация – это возможность предоставить потоку эксклюзивный доступ к объекту. Механизм синхронизации основан на концепции монитора.
    Монитор

    это объект специального назначения, в котором применен прин- цип взаимного исключения для нескольких методов. Во время выполнения программы монитор допускает лишь поочередное выполнение методов, на- ходящихся под его контролем. У каждого объекта в Java имеется свой собст- венный неявный монитор. Когда метод с атрибутом synchronized вызывается для объекта, последний обращается к монитору, чтобы определить, выполня- ет ли в данный момент какой-либо другой поток метод типа synchronized для данного объекта. Если нет, то текущий поток получает разрешение войти в монитор. Вход в монитор называется также блокировкой (locking) монитора.
    Если при этом другой поток уже вошел в монитор, то текущий поток должен ожидать до тех пор, пока другой поток не покинет его. Java гарантирует, что никакой поток не сможет выполнить синхронный метод/блок кода с тем же монитором пока он используется другим потоком. Для объявления синхрон- ного метода нужно при описании метода указать атрибут synchronized. На- пример: public synchronized void metod();
    Использование синхронизированных методов

    достаточно простой способ синхронизации потоков, обращающихся к общим критическим ресур- сам. Заметим, что не обязательно синхронизировать весь метод

    можно вы- полнить синхронизацию только критичного фрагмента кода.
    Кроме данного способа синхронизации потоков можно воспользовать- ся такими методами класса Thread, как sleep, suspend, resume, которые позво- ляют временно приостанавливать и возобновлять работу потока. Если требу-

    47 ется перевести поток в состояние ожидания, пока не завершится текущий по- ток, то можно воспользоваться методом join.
    8.4. Взаимодействие потоков
    Часто необходимо организовать взаимодействие потоков таким обра- зом, чтобы один поток управлял работой другого или других потоков. При этом важно, чтобы ожидающий поток или потоки ожидали, не используя время процессора на опрос для постоянной проверки некоторых условий. Во избежание потери времени на опрос Java использует механизм взаимодейст- вия между потоками через методы wait(),notify(),notifyall(). Все 3 метода объ- явлены в классе java.lang.Object.
    Метод wait предписывает вызвавшему потоку отдать монитор и перей- ти в состояние ожидания, пока какой-нибудь другой поток не войдет в тот же монитор и не вызовет метод notify(), или пока не истечет период времени, указанный в параметре метода wait. Метод notify() активизирует один из ожидающих потоков, вызвавших метод wait() того же объекта, а метод notifyall() активизирует все ожидающие потоки, вызвавшие метод wait() того же объекта. После активизации потоков для запуска выбирается один из них с наибольшим приоритетом. Все 3 метода служат интерфейсом для взаимо- действия с монитором объекта, и их можно вызвать только в том случае, ко- гда текущий поток владеет правами на монитор объекта, т. е. внутри метода или блока типа synchronized.
    Ниже приведен пример организации многопоточного приложения, в котором создается монитор (mutex) и 5 потоков. С помощью монитора в ме- тоде run синхронизируется доступ к блоку кода, где выполняется вывод на экран имени потока и осуществляется его задержка на 300 мс. Для наглядно- сти отображения работы приложения метод run для каждого потока выполня- ет критическую часть кода 10 раз: class ThreadTest { public static void main(String[] args) {
    Object mutex = new Object();
    // Создаем монитор
    ThreadEx [] threads = new ThreadEx[5]; // Объявляем 5 потоков
    /** Вызываем статический метод запуска потоков */ startThreads(mutex, threads);
    // Завершение потока main произойдет после завершения всех потоков joinThreads(threads);
    System.out.println("Основной поток завершен");
    }

    48 private static void startThreads (Object mutex, ThreadEx[] threads)
    { for (int i = 0; i < threads.length; i++)
    { threads[i] = new ThreadEx("Поток №" + i, mutex); threads[i].start();
    }}
    /** * Ожидание окончания потоков */ private static void joinThreads(ThreadEx[] threads)
    { for (int i = 0; i < threads.length; i++) try { threads[i].join();
    } catch (InterruptedException e) { e.printStackTrace(); }
    }
    }
    /** * Класс, описывающий поток через наследование Thread */ class ThreadEx extends Thread { private Object mutex; public ThreadEx(String name, Object mutex)
    { // Задание имени потока и его приоритета this.mutex = mutex; setName(name); setPriority(MIN_PRIORITY);
    }
    /** * Основной метод потока */ public void run() { for (int i = 0; i < 10; i++)
    { // Доступ к разделяемому коду через монитор synchronized (mutex) {
    System.out.println(getName() + " работает"); try {
    // Для эмуляции задержки доступа к ресурсу и большей наглядности
    Thread.sleep(300);
    } catch (InterruptedException e) { e.printStackTrace();
    }
    // Сообщаем монитору, что он освобождается mutex.notify(); } try {
    // Имитируем работу после освобождения ресурса
    // Без этой строчки следующий поток может не успеть захватить ресурс
    Thread.sleep(10);
    } catch (InterruptedException e) { e.printStackTrace(); }
    }
    }
    }

    49
    1   2   3   4   5   6


    написать администратору сайта