- •Аннотация
- •Лекция 1. Что такое Java? История создания.
- •1. Что такое Java?
- •2. История создания Java
- •2.1. Сложности внутри Sun Microsystems
- •2.2. Проект Green
- •2.3. Компания FirstPerson
- •2.4. World Wide Web
- •2.5. Возрождение Oak
- •2.6. Java выходит в свет
- •3. История развития Java
- •3.1. Браузеры
- •3.2. Сетевые компьютеры
- •3.3. Платформа Java
- •4. Заключение
- •5. Контрольные вопросы
- •Аннотация
- •1. Основы объектно-ориентированного программирования
- •1.1. Методология процедурно-ориентированного программирования
- •1.2. Методология объектно-ориентированного программирования
- •1.3. Объекты
- •1.3.1. Состояние.
- •1.3.2. Поведение
- •1.3.3. Уникальность
- •1.4. Классы
- •1.4.1. Инкапсуляция
- •1.4.2. Полиморфизм
- •1.5. Типы отношений между классами
- •1.5.1. Агрегация
- •1.5.2. Ассоциация
- •1.5.3. Наследование
- •1.5.4. Метаклассы
- •1.6. Достоинства ООП
- •1.7. Недостатки ООП
- •1.8. Заключение
- •1.9. Контрольные вопросы
- •Аннотация
- •Лекция 3. Лексика языка
- •1. Лексика языка
- •1.1. Кодировка
- •1.2. Анализ программы
- •1.2.1. Пробелы
- •1.2.2. Комментарии
- •1.2.3. Лексемы
- •1.3. Виды лексем
- •1.3.1. Идентификаторы
- •1.3.2. Ключевые слова
- •1.3.3. Литералы
- •1.3.3.1. Целочисленные литералы
- •1.3.3.2. Дробные литералы
- •1.3.3.3. Логические литералы
- •1.3.3.4. Символьные литералы
- •1.3.3.5. Строковые литералы
- •1.3.3.6. Null литерал
- •1.3.3.7. Разделители
- •1.3.3.8. Операторы
- •1.3.3.9. Заключение
- •1.4. Дополнение: Работа с операторами
- •1.4.1. Операторы присваивания и сравнения
- •1.4.2. Арифметические операции
- •1.4.3. Логические операторы
- •1.4.4. Битовые операции
- •1.5. Заключение
- •1.6. Контрольные вопросы
- •Аннотация
- •Лекция 4. Типы данных
- •1. Введение
- •2. Переменные
- •3. Примитивные и ссылочные типы данных
- •3.1. Примитивные типы
- •3.2. Целочисленные типы
- •4. Дробные типы
- •5. Булевский тип
- •6. Ссылочные типы
- •6.1. Объекты и правила работы с ними
- •6.2. Класс Object
- •6.3. Класс String
- •6.4. Класс Class
- •7. Заключение
- •8. Заключение
- •9. Контрольные вопросы
- •Аннотация
- •Лекция 5. Имена. Пакеты
- •1. Введение
- •2. Имена
- •2.1. Простые и составные имена. Элементы.
- •2.2. Имена и идентификаторы
- •2.3. Область видимости (введение)
- •3. Пакеты
- •3.1. Элементы пакета
- •3.2. Платформенная поддержка пакетов
- •3.3. Модуль компиляции
- •3.3.1. Объявление пакета
- •3.3.2. Импорт-выражения
- •3.3.3. Объявление верхнего уровня
- •3.4. Уникальность имен пакетов
- •4. Область видимости имен
- •4.1. "Затеняющее" объявление (Shadowing)
- •4.2. "Заслоняющее" объявление (Obscuring)
- •5. Соглашения по именованию
- •6. Заключение
- •7. Контрольные вопросы
- •Аннотация
- •Лекция 6. Объявление классов
- •1. Введение
- •2. Модификаторы доступа
- •2.1. Предназначение модификаторов доступа
- •2.2. Разграничение доступа в Java
- •3. Объявление классов
- •3.1. Заголовок класса
- •3.2. Тело класса
- •3.3. Объявление полей
- •3.4. Объявление методов
- •3.5. Объявление конструкторов
- •3.6. Инициализаторы
- •4. Дополнительные свойства классов
- •4.1. Метод main
- •4.2. Параметры методов
- •4.3. Перегруженные методы
- •5. Заключение
- •6. Контрольные вопросы
- •Аннотация
- •Лекция 7. Преобразование типов
- •1. Введение
- •2. Виды приведений
- •2.1. Тождественное преобразование
- •2.2. Преобразование примитивных типов (расширение и сужение)
- •2.3. Преобразование ссылочных типов (расширение и сужение)
- •2.4. Преобразование к строке
- •2.5. Запрещенные преобразования
- •3. Применение приведений
- •3.1. Присвоение значений
- •3.2. Вызов метода
- •3.3. Явное приведение
- •3.4. Оператор конкатенации строк
- •3.5. Числовое расширение
- •3.5.1. Унарное числовое расширение
- •3.5.2. Бинарное числовое расширение
- •4. Тип переменной и тип ее значения
- •5. Заключение
- •6. Контрольные вопросы
- •Аннотация
- •1. Введение
- •2. Статические элементы
- •3. Ключевые слова this и super
- •4. Ключевое слово abstract
- •5. Интерфейсы
- •5.1. Объявление интерфейсов
- •5.2. Реализация интерфейса
- •5.3. Применение интерфейсов
- •6. Полиморфизм
- •6.1. Поля
- •6.2. Методы
- •6.3. Полиморфизм и объекты
- •7. Заключение
- •8. Контрольные вопросы
- •Аннотация
- •Лекция 9. Массивы
- •1. Введение
- •2. Массивы, как тип данных в Java
- •2.1. Объявление массивов
- •2.2. Инициализация массивов
- •2.3. Многомерные массивы
- •2.4. Класс массива
- •3. Преобразование типов для массивов
- •3.1. Ошибка ArrayStoreException
- •3.2. Переменные типа массив, и их значения
- •4. Клонирование
- •4.1. Клонирование массивов
- •5. Заключение
- •6. Контрольные вопросы
- •Аннотация
- •Лекция 10. Операторы и структура кода
- •1. Управление ходом программы
- •2. Нормальное и прерванное выполнение операторов
- •3. Блоки и локальные переменные
- •4. Пустой оператор
- •5. Метки
- •6. Оператор if
- •7. Оператор switch
- •8. Управление циклами
- •8.1. Цикл while
- •8.2. Цикл do
- •8.3. Цикл for
- •9. Операторы break и continue
- •9.1. Оператор continue
- •9.2. Оператор break
- •10. Именованные блоки
- •11. Оператор return
- •12. Оператор synchronized
- •13.1. Причины возникновения ошибок
- •13.2. Обработка исключительных ситуаций
- •13.2.1. Конструкция try-catch
- •13.2.2. Конструкция try-catch-finally
- •13.3. Использование оператора throw
- •13.4. Обрабатываемые и необрабатываемые исключения
- •13.5. Создание пользовательских классов исключений
- •13.6. Переопределение методов и исключения
- •13.7. Особые случаи
- •14. Заключение
- •15. Контрольные вопросы
- •Аннотация
- •Лекция 11. Пакет java.awt
- •1. Введение
- •2. Апплеты
- •2.1. Тег HTML <Applet>
- •2.2. Передача параметров
- •2.3. Контекст апплета
- •2.4. Отладочная печать
- •2.5. Порядок инициализации апплета
- •2.6. Перерисовка
- •2.7. Задание размеров графических изображений
- •2.8. Простые методы класса Graphics
- •2.9. Цвет
- •2.9.1. Методы класса Color
- •2.10. Шрифты
- •2.10.1. Использование шрифтов
- •2.10.2. Позиционирование и шрифты: FontMetrics
- •2.10.3. Использование FontMetrics
- •2.10.4. Центрирование текста
- •3. Базовые классы
- •4. Основные компоненты
- •5. Менеджеры компоновки
- •6. Окна
- •7. Меню
- •8. Обработка событий
- •8.1. Рисование "каракулей" в Java
- •8.2. Рисование "каракулей" с использованием встроенных классов
- •9. Заключение
- •10. Контрольные вопросы
- •Аннотация
- •Лекция 12. Потоки выполнения. Синхронизация
- •1. Введение
- •2. Многопоточная архитектура
- •3. Базовые классы для работы с потоками
- •3.1. Класс Thread
- •3.2. Интерфейс Runnable
- •3.3. Работа с приоритетами
- •3.4. Демон-потоки
- •4. Синхронизация
- •4.1. Хранение переменных в памяти
- •4.2. Модификатор volatile
- •4.3. Блокировки
- •5. Методы wait(), notify(), notifyAll() класса Object
- •6. Контрольные вопросы
- •Аннотация
- •Лекция 13. Пакет java.lang.
- •1. Введение
- •2. Object
- •3. Class
- •4. Wrapper Classes
- •4.1. Integer
- •4.2. Character
- •4.3. Boolean
- •4.4. Void
- •5. Math
- •6. Строки
- •6.1. String
- •6.2. StringBuffer
- •7. Системные классы
- •7.1. ClassLoader
- •7.2. SecurityManager - менеджер безопасности
- •7.3. System
- •7.4. Runtime
- •7.5. Process
- •8. Потоки исполнения
- •8.1. Runnable
- •8.2. Thread
- •8.3. ThreadGroup
- •9. Исключения
- •10. Заключение
- •11. Контрольные вопросы
- •Аннотация
- •Лекция 14. Пакет java.util
- •1. Введение
- •2. Работа с датами и временем
- •2.1. Класс Date
- •2.2. Классы Calendar и GregorianCalendar
- •2.3. Класс TimeZone
- •2.4. Класс SimpleTimeZone
- •3. Интерфейс Observer и класс Observable
- •4. Коллекции
- •4.1. Интерфейсы
- •4.1.1. Интерфейс Collection
- •4.1.2. Интерфейс Set
- •4.1.3. Интерфейс List
- •4.1.4. Интерфейс Map
- •4.1.5. Интерфейс SortedSet
- •4.1.6. Интерфейс SortedMap
- •4.1.7. Интерфейс Iterator
- •4.2. Aбстрактные классы используемые при работе с коллекциями.
- •4.3. Конкретные классы коллекций
- •4.4. Класс Collections
- •5. Класс Properties
- •6. Интерфейс Comparator
- •7. Класс Arrays
- •8. Класс StringTokenizer
- •9. Класс BitSet
- •10. Класс Random
- •11. Локализация
- •11.1. Класс Locale
- •11.2. Класс ResourceBundle
- •12. Заключение
- •13. Контрольные вопросы
- •Аннотация
- •Лекция 15. Пакет java.io
- •1. Система ввода/вывода. Потоки данных (stream)
- •1.1. Классы InputStream и OutputStream
- •1.2. Классы-реализации потоков данных
- •1.2.1. Классы ByteArrayInputStream и ByteArrayOutputStream
- •1.2.2. Классы FileInputStream и FileOutputStream
- •1.2.3. PipedInputStream и PipedOutputStream
- •1.2.4. StringBufferInputStream
- •1.2.5. SequenceInputStream
- •1.3. Классы FilterInputStreeam и FilterOutputStream. Их наследники.
- •1.3.1. BufferedInputStream и BufferedOutputStream
- •1.3.2. LineNumberInputStream
- •1.3.3. PushBackInputStream
- •1.3.4. PrintStream
- •1.3.5. DataInputStream и DataOutputStream
- •2. Serialization
- •2.1. Версии классов
- •3. Классы Reader и Writer. Их наследники.
- •4. Класс StreamTokenizer
- •5. Работа с файловой системой.
- •5.1. Класс File
- •5.2. Класс RandomAccessFile
- •6. Заключение
- •7. Контрольные вопросы
- •Аннотация
- •Лекция 16. Введение в сетевые протоколы
- •1. Основы модели OSI
- •2. Physical layer (layer 1)
- •3. Data layer (layer 2)
- •3.1. LLC sublayer.
- •3.2. MAC sublayer.
- •4. Network layer (layer 3)
- •4.1. Class A
- •4.2. Class B
- •4.3. Class CClass DClass E
- •5. Transport layer (layer 4)
- •6. Session layer (layer 5)
- •7. Presentation layer (layer 6)
- •8. Application layer (layer 7)
- •9. Утилиты для работы с сетью
- •9.1. IPCONFIG (IFCONFIG)
- •9.3. Ping
- •9.4. Traceroute
- •9.5. Route
- •9.6. Netstat
- •9.7. Задания для практического занятия
- •10. Пакет java.net
- •11. Заключение
- •12. Контрольные вопросы
Стр. 19 из 24
5. Методы wait(), notify(), notifyAll() класса Object
Наконец, переходим к рассмотрению трех методов класса Object, которое завершает описание механизмов поддержки многопоточности в Java.
Каждый объект в Java имеет не только блокировку для synchronized блоков и методов, но и так называемый wait-set, набор потоков исполнения. Любой поток может вызвать метод wait() любого объекта и таким образом попасть в его wait-set. При этом выполнение такого потока приостанавливается до тех пор, пока другой поток не вызовет у точно этого же объекта метод notifyAll(), который пробуждает все потоки из wait-set. Метод notify() пробуждает один, случайно выбранный поток из этого набора.
Однако применение этих методов связано с одним важным ограничением. Любой из них может быть вызван потоком у объекта только после установления блокировки на этот объект. То есть, либо внутри synchronized-блока с ссылкой на этот объект в качестве аргумента, либо обращение к методам должны быть в синхронизированных методах класса самого объекта. Рассмотрим пример:
public class WaitThread implements Runnable { private Object shared;
public WaitThread(Object o) { shared=o;
}
public void run() { synchronized (shared) { try {
shared.wait();
} catch (InterruptedException e) {} System.out.println("after wait");
}
}
public static void main(String s[]) { Object o = new Object();
WaitThread w = new WaitThread(o); new Thread(w).start();
try { Thread.sleep(100);
} catch (InterruptedException e) {} System.out.println("before notify"); synchronized (o) {
o.notifyAll();
}
}
}
Программирование на Java
Rendered by www.RenderX.com
Стр. 20 из 24 |
Методы wait(), notify(), notifyAll() класса Object |
Результатом программы будет:
before notify after wait
Обратите внимание, что метод wait(), также как и sleep(), требует обработки InterruptedException, то есть его выполнение также можно прервать методом interrupt().
В заключение рассмотрим более сложный пример для трех потоков:
public class ThreadTest implements Runnable { final static private Object shared=new Object();
private int type;
public ThreadTest(int i) { type=i;
}
public void run() {
if (type==1 || type==2) { synchronized (shared) { try {
shared.wait();
} catch (InterruptedException e) {} System.out.println("Thread "+type+
" after wait()");
}
} else {
synchronized (shared) { shared.notifyAll(); System.out.println("Thread "+type+
"after notifyAll()");
}
}
}
public static void main(String s[]) { ThreadTest w1 = new ThreadTest(1); new Thread(w1).start();
try { Thread.sleep(100);
} catch (InterruptedException e) {}
ThreadTest w2 = new ThreadTest(2); new Thread(w2).start();
try { Thread.sleep(100);
} catch (InterruptedException e) {}
Программирование на Java
Rendered by www.RenderX.com
Стр. 21 из 24
ThreadTest w3 = new ThreadTest(3); new Thread(w3).start();
}
}
Результатом работы программы будет:
Thread 3 after notifyAll()
Thread 1 after wait()
Thread 2 after wait()
Рассмотрим, что происходило. Во-первых, был запущен поток 1, который тут же вызвал метод wait() и приостановил свое выполнение. Затем то же самое произошло с потоком 2. Далее начинает выполняться поток 3.
Сразу обращает на себя внимание следующий факт. Еще поток 1 вошел в synchronizedблок, а стало быть установил блокировку на объект shared. Но судя по результатам видно, что это не помешало и потоку 2 затем зайти в synchronized-блок, а потом и потоку 3. Причем для последнего это просто необходимо, иначе как можно "разбудить" потоки 1 и 2?
Можно сделать вывод, что потоки, прежде чем приостановить выполнение после вызова метода wait(), отпускают все занятые блокировки. Итак, вызывается метод notifyAll(). Как уже было сказано, все потоки из wait-set возобновляют свою работу. Однако чтобы корректно продолжить исполнение необходимо вернуть блокировку на объект, ведь следующая команда также находится внутри synchronized-блока!
Получается, что даже после вызова notifyAll() все потоки не могут сразу возобновить работу. Лишь один из них сможет вернуть себе блокировку и продолжить работу. Когда он покинет свой synchronized-блок и отпустит объект, второй поток возобновит свою работу и так далее. Если по какой-то причине объект так и не будет освобожден, поток так никогда и не выйдет из метода wait(), даже если будет вызван метод notifyAll(). В рассмотренном примере потоки один за другим смогли возобновить свою работу.
Кроме этого определен метод wait() с параметром, который задает период тайм-аута, по истечении которого поток сам попытается возобновить свою работу. Но начать ему придется все равно с повторного получения блокировки.
6. Контрольные вопросы
12-1. Каким образом на однопроцессорной машине исполняются многопоточные приложения?
a.) Операционная система разделяет рабочее время процессора на небольшие интервалы. В начале каждого интервала решается, какая из задач будет выполняться на его протяжении. Поскольку процессор переключается между задачами очень быстро, возникает ощущение, что они выполняются одновременно. Этот прием называется time-slicing.
12-2. Какие преимущества дает многопоточная архитектура?
Программирование на Java
Rendered by www.RenderX.com
Стр. 22 из 24 |
Контрольные вопросы |
a.) Основные преимущества:
•Если сама проектируемая система предназначена для выполнения нескольких действий одновременно (например, сервер, обслуживающий нескольких клиентов сразу), то, воспользовавшись встроенной многозадачностью, можно существенно упростить архитектуру системы, повысив ее надежность и быстродействие.
•Если необходимо выполнить несколько действий, которые требуют различных аппаратных и других ресурсов (память, жесткий диск, сеть, принтер, монопольный доступ к БД и т.д.), то одновременное выполнение этих задач потребует меньше времени, чем выполнение их по отдельности.
•Воспользовавшись свойством приоритетов потоков можно настроить систему так, чтобы она была наиболее удобна пользователю. Пусть формально процессор выполнит меньше вычислений, но они будут более полезны клиенту.
12-3. Что такое приоритет потока?
a.) Приоритет – это характеристика, как правило, числовая, которая влияет на распределение интервалов работы процессора между задачами. Предсказать количественный эффект от изменения приоритета в ту или иную сторону нельзя, но задача с большим приоритетом всегда получает больше времени, чем с меньшим приоритетом.
12-4. Что такое демон-поток?
a.) Демон-поток – это обычный поток. Единственно отличие от не-демонов заключается в том, что виртуальная машина закрывается, когда остаются рабочими только демон-потоки.
12-5. Когда закрывается виртуальная машина, выполняющая программу с несколькими потоками исполнения?
a.) Когда остаются рабочими только демон-потоки, либо не остается ни одного потока.
12-6. Для чего служит в Java класс Thread?
a.) Класс Thread служит для запуска потока, изменения его свойств и дальнейшего управления им (приостановка, возобновление работы, остановка и т.д.).
12-7. Поскольку интерфейс Runnable представляет собой альтернативный способ программировать потоки исполнения, можно ли в такой программе обойтись вовсе без класса Thread?
a.) Нет, поскольку для создания и запуска потока всегда необходимо создавать экземпляр класса Thread или его наследника. Также он необходим для дальнейшего управления потоком.
12-8. Что такое локальное и главное хранилища в Java? Чем они различаются?
Программирование на Java
Rendered by www.RenderX.com
Стр. 23 из 24
a.) JVM поддерживает одно главное хранилище, в котором хранятся значения всех переменных, созданных программой. Локальное хранилище создается для каждого потока. После создания оно пустое, и поток должен скопировать те переменные, с которыми работает, в свою локальную память. Взаимодействие между главным и локальными хранилищами строго регламентировано. В частности, любая переменная создается сначала в главной, а затем копируется в локальную память.
12-9. Если один поток начал исполнение synchronized-блока, указав ссылку на некий объект, может ли другой поток обратиться к полю этого объекта? К методу?
a.) К любому полю можно обратиться беспрепятственно, равно как и к неsynchronized методу. Вызов synchronized-метода потребует установки блокировки, а до этого второй поток будет приостановлен.
12-10. Если объявить метод synchronized, то какой эффект будет этим достигнут?
a.) Гарантируется, что в один момент времени только один поток может его выполнять.
12-11. Как работают static synchronized методы?
a.) Аналогично обычным synchronized методам, только блокировка устанавливается не на объект класса, а на объект класса Class, описывающий исходный класс. Таким образом, гарантируется, что в один момент времени только один поток может работать со static synchronized методами класса.
12-12. Почему метод wait требует обработки InterruptedException, а методы notify и notifyAll
– нет?
a.) Потому что вызов метода wait приводит к приостановке потока, работу которого можно возобновить, вызвав метод interrupt(), что и приведет к возникновению исключительной ситуации InterruptedException.
Методы notify и notifyAll не приостанавливают работу потока.
12-13. Может ли поток никогда не выйти из метода wait, даже если будет вызван метод notify? notifyAll?
a.) Поскольку метод wait может быть корректно вызван только при наличии блокировки на объект, а после успешного вызова поток эту блокировку освобождает, то для возобновления работы поток должен снова установить блокировку. Если по каким-то причинам она постоянно «занята», то поток никогда не выйдет из метода wait.
12-14. Какой будет результат работы следующего кода?
public abstract class Test implements Runnable { private Object lock = new Object();
public void lock() { synchronized (lock) {
Программирование на Java
Rendered by www.RenderX.com
Стр. 24 из 24 |
Контрольные вопросы |
try { lock.wait();
System.out.println(“1”);
} catch (InterruptedException e) {
}
}
}
public void unlock() { synchronized (lock) { lock.notify(); System.out.println(“2”);
}
}
public static void main(String s[]) { new Thread(new Test() {
public void run() { lock();
}
}).start();
new Thread(new Test() { public void run() { unlock();
}
}).start();
}
}
a.) На консоли появится только число 2, а виртуальная машина никогда не завершит работу, поскольку первый поток никогда не выйдет из метода wait. Хотя второй поток и вызывает метод notify, однако потоки работают с разными объектами (у каждого свое поле lock), что и приводит к описанному эффекту.
Программирование на Java
Rendered by www.RenderX.com