Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
nybok PZ (Восстановлен).docx
Скачиваний:
47
Добавлен:
01.03.2016
Размер:
1.43 Mб
Скачать

1 Системотехническое проектирование

    1. Выбор языка программирования

Целью дипломного проекта является разработка программного обеспечения для удаленного контроля приборов “АЛКОНТ”. Важным этапом является выбор языка программирования.

Преимущество языка Javaдля пользователейInternetиWorldWideWedзаключается в появлении безопасных платформено–независимых приложений, которые могут использоваться в любом узлеInternet. Программисты, создающие приложения наJava, пишут свой код всего один раз – им не приходится “переносить” свои приложения на все возможные программные и аппаратные платформы[1].

Многие рассматривают Javaв первую очередь как средство создания аплетов дляWorldWideWed. Термином “аплет” вJavaобозначается мини–приложение, работающее внутриWed–страницы. После того как аплет загружен на компьютер пользователя, он может выполнять определенные задачи и взаимодействовать с пользователем через браузер, не требуя ресурсовWeb–сервера. Разумеется, некоторые аплеты могут взаимодействовать с сервером для решения своих внутренних задач.

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

Кроме того, Javaиспользуется как язык программирования общего назначения для реализации тех проектов, в которых платформенная независимость не так важна. Простота программирования и средств безопасности позволяют быстро создавать отлаженный код. Некоторые распространенные в других языках ошибки в программах наJavaв общем не встречаются благодаря таким средствам, как сборка мусора и ссылки, безопасные по отношению к типам. Современные приложения, работающие в сетевых условиях и применяющие графический пользовательский интерфейс, которым приходятся одновременно обслуживать несколько задач, используют поддержку многопоточности вJava, а механизм исключений облегчает обработку ошибок. Несмотря на всю мощь своих встроенных средств,Java– это простой язык, который быстро осваивается программистами.

Виртуальная машина Java(JVM). Программы на Java транслируются в байт–код, выполняемый виртуальной машиной Java (JVM) — программой, обрабатывающей байтовый код и передающей инструкции оборудованию как интерпретатор. Достоинство подобного способа выполнения программ — в полной независимости байт–кода от операционной системы и оборудования, что позволяет выполнять Java–приложения на любом устройстве, для которого существует соответствующая виртуальная машина. Другой важной особенностью технологии Java является гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной. Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером) вызывают немедленное прерывание. РаботаJava c другими платформами изображена на рисунке 1.1.

Рисунок 1.1 – Подготовка приложения для работы на разных платформах

Часто к недостаткам концепции виртуальной машины относят то, что исполнение байт–кода виртуальной машиной может снижать производительность программ и алгоритмов, реализованных на языке Java. В последнее время был внесен ряд усовершенствований, которые несколько увеличили скорость выполнения программ на Java:

– применение технологии трансляции байт–кода в машинный код непосредственно во время работы программы (JIT–технология) с возможностью сохранения версий класса в машинном коде;

– широкое использование платформенно–ориентированного кода (native–код) в стандартных библиотеках;

– аппаратные средства, обеспечивающие ускоренную обработку байт–кода (например, технология Jazelle, поддерживаемая некоторыми процессорами фирмы ARM).

Многопоточность Java. Организация потоков в среде Java позволяет добиться прироста производительности практически во всех приложениях. Узнайте, как многопоточность становится стандартным средством программирования в среде Java, благодаря технологии Hyper–Threading и возможностям новых многоядерных процессоров Intel®[2].

Разработка приложений на основе потоков, то есть особых последовательностей команд, обеспечивает значительный прирост производительности. Рассмотрим, например, программу–проигрыватель DVD, которая считывает большие объемы данных с компакт–диска, обрабатывает их и выводит изображение на экран. Обычные однопоточные программы – а это большинство современных клиентских программ выполняют перечисленные действия последовательно. В данном примере обработка данных начнется лишь после того, как с диска будет считан определенный объем информации. Производительность такой программы невысока: ресурсы, которые могут использоваться для обработки, не будут задействованы, пока идет считывание следующей порции информации с диска.

В многопоточной версии проигрывателя один поток предназначался бы для считывания информации, второй – для обработки, а третий – для записи данных в видеобуфер, причем все они выполнялись бы параллельно, а обработка продолжалась бы даже во время чтения с диска – прирост производительности налицо! Можно привести еще много примеров, когда одновременное выполнение нескольких действий приводит к повышению производительности системы. Именно для увеличения производительности и реализована многопоточность в виртуальной машине Java(JVM).

В данной статье освещаются следующие вопросы: реализация многопоточности в коде Java, оптимальная разработка параллельных программ, а также использование средств и ресурсов для разработчиков. Так как подробное рассмотрение всех вопросов не умещалось в рамках одной статьи, автор затронул в ней лишь ключевые детали. Подробную информацию об интересующих вопросах вы сможете получить из дополнительных ресурсов.

Организация многопоточности Java. При запуске любой программы образуется, по крайней мере, один поток. В С/С++ и Java этот поток запускается при вызове метода main(). Для создания дополнительных потоков необходимо их запустить и назначить им определенные функции, после выполнения которых потоки автоматически будут завершены виртуальной машиной. В среде Java для создания потока и назначения им функций есть два способа. Первым из них является наследование от класса Thread (входящего в пакет java.lang) с последующим переопределением метода run() на функцию, которую вы хотите назначить для потока.

Таким образом, происходит наследование от класса Thread с запуском переопределенного метода run(). В среде Java для создания потока и назначения им функций есть два способа. Первым из них является наследование от класса Thread (входящего в пакет java.lang) с последующим переопределением метода run() на функцию, которую вы хотите назначить для потока. Пример кода на рисунке 1.2.

Рисунок 1.2 – Описание метода run()

Таким образом, происходит наследование от класса Thread с запуском переопределенного метода run(). Назначенная функция организует цикл, при котором на экран выводится строка, после чего программа останавливается на случайный интервал времени. После 10 итераций цикла на экран выводится слов “DONE!”, а поток завершается, так как функция закончила свое выполнение. Ниже приведен пример функции для создания потока, смотрите рисунок 1.3.

Таким образом, происходит наследование от класса Thread с запуском переопределенного метода run(). Назначенная функция организует цикл, при котором на экран выводится строка, после чего программа останавливается на случайный интервал времени. После 10 итераций цикла на экран выводится слов “DONE!”, а поток завершается, так как функция закончила свое выполнение. Ниже приведен пример функции для создания потока, смотрите рисунок 1.3.

Рисунок 1.3– Cоздание потока

Второй способ создания потока – использование класса с реализацией интерфейса Runnable (также из пакета java.lang). Этот интерфейс определит метод run(), который будет выполнять основную функцию потока, аналогично описанному выше первому способу.

Реализация многопоточности Java. Многопоточность, которую организуют для повышения производительности, значительно усложняет программный код, особенно если необходимо предусмотреть взаимодействие потоков. Важно разобраться с премудростями организации потоков, так как чем больше ядер в процессорах Intel®, тем больше потоков приходится предусматривать в программном коде. Недостаточная компетенция разработчика при организации многопоточности несомненно приведет к возникновению множества ошибок в программе, поэтому давайте перейдем к рассмотрению решений некоторых возможных сложностей. Ожидание завершения другого потока: предположим, нам нужно обработать целочисленный массив. Это можно делать последовательно, обрабатывая одно значение массива за другим, или, что более продуктивно, параллельно – созданием нескольких потоков, каждому из которых назначена определенная область массива. Допустим, чтобы перейти к следующей стадии обработки, нам необходимо дождаться завершения всех потоков. Для синхронизации взаимодействия потоков используется метод join(). При его задействовании запуск определенного потока произойдет после завершения другого. Таким образом, поток “В” будет ждать завершения потока “А”. При превышении времени ожидания, назначенного в методе join(), поток В займется обработкой других данных, если поток “А” еще не завершен. Итак, мы обсудили самую сложную задачу при организации многопоточности – проблему ожидания завершения потоков. Вернемся к ней позже.

Ожидание доступа к заблокированным объектам: предположим, мы занимаемся разработкой системы бронирования билетов для аэропорта. Чаще всего многопоточность в таких программах организована таким образом, что каждому подключенному к системе пользователю, а также всем кассирам назначены отдельные потоки (организация очень больших систем может отличаться от описанной). Если два пользователя одновременно попытаются забронировать одно и то же место, а в программе эта возможность не предусмотрена, произойдет следующее: один поток обратится к конкретному ресурсу одновременно с другим потоком. В результате оба пользователя решат, что они забронировали себе нужный билет на самолет.

Для того чтобы предотвратить изменение одних и тех же данных разными потоками, необходимо, чтобы один поток заблокировал доступ к ним для другого потока. Тогда при попытке второго потока изменить данные, ему придется ждать, пока первый поток не снимет свою блокировку. В нашем примере второй поток обнаружит, что данное место уже было зарезервировано, и выдаст соответствующее предупреждение пользователю. Ситуация, описанная выше, называется "состоянием гонки” (race condition), и ее последствия могут быть очень пагубными. Вот почему на время выполнения операций с данными одним потоком принято блокировать доступ к этим данным для других потоков.

В среде Java блокировку можно реализовать несколькими способами. Наиболее частым является использование ключевого слова “synchronized”. Метод, содержащий это ключевое слово, может выполняться только одним потоком, а после выполнения метода блокировка снимается.

Исключительные ситуации в Java. Как мы видим, все исключения имеют общего предка – Throwable. Он имеет два важных подкласса – Exception и Error. Исключения (Exceptions) являются результатом возникших внутри программы проблем, которые в принципе решаемы и предсказуемы. Ошибки (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться перехватить в приложении, написанном достаточно рационально (например ошибка OutOfMemoryError происходит в тех случаях, когда JVM не хватает памяти для выполнения программы). Кроме того, у Exception есть важный потомок – RuntimeException (исключение времени выполнения). Этот класс и его потомки представляют собой исключения, которые возникают во время “нормальной работы Java–машины” (примерами таких исключений являются попытки использования нулевых ссылок на объекты, деления на ноль или выход за границы массива).

В Java все исключения делятся на три типа: контролируемые исключения(checked), ошибки (Errors) и исключения времени выполнения (RuntimeExceptions) – последние два типа также объединяют в категорию неконтролируемых (unchecked) исключений. В чем различие? Все очень просто контролируемые исключения представляют собой те ошибки, которые могут быть обработаны в ходе выполнения программы, как вы уже догадались к этому типу относятся все потомки класса Exception (но не RuntimeException). Контролируемые исключения обязательны для обработки в коде программы, они должны быть обработаны либо включением в блок try–catch, либо объявлены в сигнатуре метода.

Неконтролируемые (unchecked) исключения не требуют обязательной обработки, поскольку представляют собой те ситуации, когда ошибка не зависит непосредственно от программиста (например произошёл сбой в аппаратном обеспечении), либо те, когда ошибку обрабатывать не имеет смысла, т.к. проще внести изменения в код – к ним относятся все потомки классов Error и RuntimeException, смотрите рисунок 1.4.

Рисунок 1.4 – Иерархия классов исключений

Защищенность Java. Поскольку язык Java предназначен для использования в сетевой или распределенной среде, то вопросам его безопасности было уделено большое внимание. На данный момент язык Java позволяет создавать системы, надежно защищенные от вирусов и несанкционированного доступа.

Но 100% безопасности не может обеспечить ни один язык программирования, ведь все предусмотреть невозможно. Первые дыры в Java были найдены экспертами по вопросам безопасности из Пристонского университета еще в версии Java 1.0. Можно сказать, что все новые ошибки находятся до сих пор, но от этого не застрахован ни один язык программирования.

Тем не менее, специалисты компании Sun делают все, чтобы своевременно устранить бреши в безопасности JDK. Так, компания опубликовала внутренние спецификации интерпретатора языка Java и привлекла к поиску ошибок независимых специалистов в области безопасного ПО.

Обнаруженные на данный момент ошибки очень немногочисленны.

Вот лишь небольшой список ситуаций, возникновение которых предотвращает система безопасности языка Java:

– переполнение стека выполняемой программы, к которому приводили некоторые черви;

– повреждение участков памяти, которые находятся за пределами пространства, выделенного процессу;

– считывание и запись локальных файлов при использовании безопасного загрузчика классов.

Все меры безопасности вполне уместны и обычно работают без проблем, но осмотрительность никогда не повредит. Со временем в язык были добавлены новые средства защиты. Начиная с версии 1.1, в языке Java появилось понятие классов с цифровой подписью. Пользуясь классом с цифровой подписью, вы можете быть уверенными в его авторе. Если вы ему доверяете, то можете предоставить этому классу все привилегии, доступные на вашей машине.

Альтернативный механизм доставки кода, предложенный компанией Microsoft, опирается на технологию ActiveX и для безопасности использует только цифровые подписи. Но этого недостаточно, ведь любой пользователь ПО фирмы Microsoft может подтвердить, что программы даже известных производителей часто завершаются аварийно, создавая тем самым опасность повреждения данных.

В тоже время система безопасности в языке Java намного надежнее технологии ActiveX, поскольку она самостоятельно контролирует приложение с момента его запуска и не позволяет ему причинить ущерб.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]