- •Методические указания по выполнению срс Программирование на языке java
- •Введение
- •1. Java - объектно-ориентированный язык программирования
- •1.1. Базовые типы данных
- •1.2. Операции (operators) в языке Java
- •1.2.1. Операции сравнения
- •1.2.2. Операции инкремента, декремента
- •1.3. Литералы (константы)
- •1.5. Массивы в Java
- •1.4. Операторы
- •1.6. Комментарии
- •1.7. Первая программа на языке Java
- •1.8. Цель, требования и рекомендации к выполнению задания
- •1.9. Задания
- •2. Абстрактные классы и Интерфейсы
- •2.1. Абстрактные классы
- •2.2. Интерфейсы
- •2.3. Цель, требования и рекомендации к выполнению задания
- •2.4. Задания
- •2.5. Пример выполнения задания.
- •3. Знакомство с библиотекой Swing
- •3.1. Основы оконной графики
- •3.2. Модель событий в Swing
- •3.3. Цель, требования и рекомендации к выполнению задания
- •3.4. Задания
- •3.5. Пример выполнения задания.
- •4. Апплеты
- •4.1. Проблема безопасности
- •4.2. Создание апплетов
- •4.3. Апплеты и приложения
- •4.4. Цель, требования и рекомендации к выполнению задания
- •4.5. Задания
- •4.6. Пример выполнения задания.
- •4.6.1. Запуск апплетов
- •4.6.2. Пример выполнения задания 2
- •5. Множественные нити выполнения (Multiple threads).
- •5.1. Реализация многопоточности в Java
- •5.1.1. Методы класса Thread
- •5.1.2. Реализация интерфейса Runnable
- •5.3. Завершение и останов нити
- •5.4. Приоритеты нитей
- •5.5. Средства синхронизации нитей в Java
- •5.6. Применение многопоточности для анимации
- •5.7. Цель, требования и рекомендации к выполнению задания
- •5.8. Задания
- •5.9. Пример выполнения задания.
- •Дополнительная информация и список литературы
- •Оглавление
5.9. Пример выполнения задания.
Напишем апплет Rectangles (рис. 6). Он создает три потока. Первый поток рисует в окне аплета прямоугольники случайного размера и цвета, второй - эллипсы, а третий управляет потоком рисования эллипсов.
Рис. 6. Окно аплета Rectangles
Расположение прямоугольников и эллипсов также выбирается случайно.
В этом приложении мы создаем на базе класса Thread три класса. Первый из них предназначен для создания потока рисования прямоугольников, второй - для создания потока рисования закрашенных эллипсов, а третий - для управления потоком рисования эллипсов.
Что же касается основного класса аплета, то он унаследован, как обычно, от класса Applet и не реализует интерфейс Runnable:
import java.applet.*;
import java.awt.*;
public class Rectangles extends Applet
{
DrawRectangles m_DrawRectThread = null;
DrawEllipse m_DrawEllipseThread = null;
NotifyTask m_NotifyTaskThread = null
// Эти поля являются ссылками на классы, соответственно DrawRectangles,
// DrawEllipse и NotifyTask . Первый из них создан для рисования
// прямоугольников, второй - эллипсов, а третий - для управления потоком
// рисования эллипсов. Указанные поля инициализируются значением null,
// что соответствует неработающим или не созданным задачам.
public String getAppletInfo()
{
return "Name: Rectangles";
}
public void paint(Graphics g)
{
Dimension dimAppWndDimension = getSize();
g.setColor(Color.yellow);
g.fillRect(0, 0,
dimAppWndDimension.width - 1,
dimAppWndDimension.height - 1);
g.setColor(Color.black);
g.drawRect(0, 0,
dimAppWndDimension.width - 1,
dimAppWndDimension.height - 1);
}
public void start()
{
// Метод start класса Rectangles Этот метод последовательно создает
// три потока и запускает их на выполнение
if (m_DrawRectThread == null)
{
m_DrawRectThread =
new DrawRectangles(this);
m_DrawRectThread.start(); // 1-ый поток
}
if (m_DrawEllipseThread == null)
{
m_DrawEllipseThread =
new DrawEllipse(this);
m_DrawEllipseThread.start(); // 2-ой поток
}
if (m_NotifyTaskThread == null)
{
m_NotifyTaskThread =
new NotifyTask(m_DrawEllipseThread);
m_NotifyTaskThread.start();// 3-ий поток
}
}
// Когда пользователь покидает страницу сервера Web с апплетом, метод
// stop класса Rectangles последовательно останавливает рисования
// прямоугольников и эллипсов, а также управляющий поток:
public void stop()
{
if (m_DrawRectThread != null)
{
m_DrawRectThread.stop();
m_DrawRectThread = null;
}
if (m_DrawEllipseThread == null)
{
m_DrawEllipseThread.stop();
m_DrawEllipseThread = null;
}
if (m_NotifyTaskThread != null)
{
m_NotifyTaskThread.stop();
m_NotifyTaskThread = null;
}
}
}
// Класс DrawRectangles определен для потока рисования прямоугольников
// В поле g класса хранится контекст отображения окна апплета, а в поле
// dimAppWndDimension – размеры этого окна: Значения этих полей
// определяются конструктором класса по ссылке на главный класс апплета.
class DrawRectangles extends Thread
{
Graphics g;
Dimension dimAppWndDimension;
public DrawRectangles(Applet Appl)
{
g = Appl.getGraphics(); // В качестве параметра конструктору передается
// ссылка на класс апплета
dimAppWndDimension = Appl.getSize();
//Конструктор использует эту ссылку для получения и сохранения в полях
// класса контекста отображения и размеров окна апплета
}
// Программный код метода run работает в рамках отдельного потока.
// Он рисует в окне апплета закрашенные прямоугольники. Прямоугольники
// имеют случайные координаты, расположение и цвет. Для того чтобы
// рисовать, необходимо получить контекст отображения. Этот контекст был
// получен конструктором класса DrawRectangles и может быть использован
// методом run. // Вооружившись контекстом отображения и размерами окна
// апплета, поток входит в бесконечный цикл рисования прямоугольников.
// В качестве генератора случайных чисел мы используем метод random из
// класса Math, который при каждом вызове возвращает новое случайное
// число типа double, лежащее в диапазоне значений от 0.0 до 1.0.
// Координаты по осям X и Y рисуемого прямоугольника определяются
// простым умножением случайного числа, полученного от метода random,
// соответственно, на ширину и высоту окна апплета:
public void run()
{
while (true)
{
int x, y, width, height;
int rColor, gColor, bColor;
x = (int)(dimAppWndDimension.width * Math.random());
y = (int)(dimAppWndDimension.height * Math.random());
width = (int)(dimAppWndDimension.width * Math.random()) / 2;
height = (int)(dimAppWndDimension.height * Math.random()) / 2;
rColor = (int)(255 * Math.random()); // Для случайного выбора цвета
gColor = (int)(255 * Math.random());// прямоугольника вычисляем
bColor = (int)(255 * Math.random()); // отдельные цветовые компоненты,
// умножая значение, полученное от метода random, на 255
g.setColor(new Color(rColor, gColor, bColor)); //цвет устанавливается в
// контексте отображения методом setColor
g.fillRect(x, y, width, height);
try // После рисования прямоугольника метод run задерживает свою
// работу на 50 миллисекунд, вызывая метод sleep:
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
stop();
} // Для обработки исключения InterruptedException, которое может
} // возникнуть во время работы этого метода, предусмотриv блок.
} // try – catch. При возникновении указанного исключения работа
} // потока останавливается вызовом метода stop
class DrawEllipse extends Thread
{ // Класс DrawEllipse очень похож на только что
Graphics g; // рассмотренный класс DrawRectangles
Dimension dimAppWndDimension;
public DrawEllipse(Applet Appl)
{
g = Appl.getGraphics();
dimAppWndDimension = Appl.getSize();
}
public synchronized void run()
{
while (true)
{
int x, y, width, height;
int rColor, gColor, bColor;
x = (int)(dimAppWndDimension.width * Math.random());
y = (int)(dimAppWndDimension.height * Math.random());
width = (int)(dimAppWndDimension.width * Math.random()) / 2;
height = (int)(dimAppWndDimension.height * Math.random()) / 2;
rColor = (int)(255 * Math.random());
gColor = (int)(255 * Math.random());
bColor = (int)(255 * Math.random());
g.setColor(new Color(rColor, gColor, bColor));
g.fillOval(x, y, width, height);
try
{
this.wait();
}
catch (InterruptedException e)
{
}
}
}
}
class NotifyTask extends Thread
{ // В классе NotifyTask мы определили одно поле STask класса Thread.
// Это поле которое хранит ссылку на поток, работой которого управляет
// данный класс:
Thread STask;
public NotifyTask(Thread SynchroTask)
{
STask = SynchroTask;
}
// Метод run класса NotifyTask периодически разблокирует поток рисования
// эллипсов, вызывая для этого метод notify в цилке с задержкой 30
// миллисекунд. Обращение к объекту STask, который хранит ссылку
// на поток рисования эллипсов, выполняется с использованием синхронизации:
public void run()
{
while (true)
{
try
{
Thread.sleep(30);
}
catch (InterruptedException e)
{
}
synchronized(STask)
{
STask.notify();
} } } }
