Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metodichka_Po_Tp.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.44 Mб
Скачать

3.4 Группы потоков

Все потоки в языке Java должны входить в состав группы потоков. В классе Thread имеется три конструктора, которые дают возможность указывать, в состав какой группы должен входить данный создаваемый поток.

Группы потоков особенно полезны, поскольку внутри их можно запустить или приостановить все потоки, а это значит, что при этом не потребуется иметь дело с каждым потоком отдельно. Группы потоков предоставляют общий способ одновременной работы с рядом потоков, что позволяет значительно сэкономить время и усилия, затрачиваемые на работу с каждым потоком в отдельности.

В приведенном ниже фрагменте программы создается группа потоков под названием genericGroup (родовая группа). Когда группа создана, создаются несколько потоков, входящих в ее состав:

ThreadGroup genericGroup=new ThreadGroup("My generic group");

Thread t1=new Thread(genericGroup,this);

Thread t2=new Thread(genericGroup,this);

Thread t3=new Thread(genericGroup,this);

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

Если при создании нового потока не указать, к какой конкретной группе он принадлежит, этот поток войдет в состав группы потоков main (главная группа) языка Java. Иногда ее еще называют текущей группой потоков. В случае апплета main может и не быть главной группой. Право присвоения имени принадлежит WWW-броузеру. Для того, чтобы определить имя группы потоков, можно воспользоваться методом getName() класса ThreadGroup.

Для того, чтобы определить к какой группе принадлежит данный поток, используется метод getThreadGroup(), определенный в классе Thread. Этот метод возвращает имя группы потоков, в которую можно послать множество методов, которые будут применяться к каждому члену этой группы.

Группы потоков поддерживают понятие привилегия доступа. Если не указать тип привилегии доступа для группы, то потоки этой группы смогут осуществлять запросы и поиск информации о потоках в других группах.

По умолчанию создаваемым потокам не присваивается определенный уровень защиты. В результате любой поток из любой группы может свободно контролировать и изменять потоки в других группах. Однако можно использовать абстрактный класс SecurityManager для указания ограничений доступа к определенным группам потоков. Для этого необходимо создать подкласс класса SecurityManager и заменить те методы, которые используются для защиты потоков. В основном эта процедура применима для потоков приложений, так как некоторые WWW-броузеры не позволяют заменить уровни защиты.

4. Приложение VertScroller

Задание. Создать апплет двойного назначения VertScroller, в окне которого отображаются строки текста, медленно всплывающие вверх. Для выполнения плавного сдвига создать поток, который периодически рисует новые строки в нижней части окна, сдвигая перед этим старые строки вверх. Основной класс апплета должен реализовывать интерфейс Runnable, поэтому для реализации многозадачности не нужно создавать подкласс класса Thread.

Методические указания. Апплет должен быть создан на основе шаблонов, содержащихся в Приложении 6 (или при помощи системы Java Applet Wizard).

Объявление элементов класса апплета.

В классе апплета объявим следующие элементы:

// выводимые строки

String strs[]={"First string", "Second string", "Third string"};

// текущий размер окна апплета

Dimension appSize;

Перерисовка окна апплета (метод paint()).

Для перерисовки изображения в окне используется метод paint(), которому передается объект g типа Graphics (g - контекст отображения для окна). Методами этого класса пользуются для вывода графической информации в окно апплета.

В данном апплете этот метод используется для определения текущего размера appSize окна и для закраски фона окна и рисовании рамки окна. Сначала раскрасим фон окна и нарисуем рамку окна. Для этого сделаем следующие действия: при помощи метода size() класса апплета получим текущий размер окна и присвоим ссылку на него объекту appSize; методом g.setColor() выберем цвет фона Color.yellow; зарисуем всю внутреннюю область окна с помощью метода g.fillRect() и объекта appSize; методом g.setColor() выберем цвет рамки Color.black; нарисуем рамку вокруг окна методом g.drawRect(), используя объект appSize.

Метод, работающий в рамках отдельного потока (метод run()).

Поток, выполняющийся в рамках метода run() одновременно с кодом апплета, будет по очереди извлекать строки из массива strs и отображать их в нижней части окна: Сначала определим переменные метода и получим контекст окна апплета и высоту символов текущего шрифта:

public void run()

{ int counter=0; // счетчик сдвигов

int current=0; // номер текущей рисуемой строки

int hy=1; // размер сдвига по вертикали

Graphics g=getGraphics(); // контекст окна апплета

int yChar=g.getFontMetrics().getHeight(); // высота символа

while (true)

{ try

{ // вывод в окно апплета

Thread.sleep(50);

}

catch (InterruptedException e)

{ stop();

}

}

}

В блоке try метода run() выполним свертку окна апплета: 1) с помощью метода g.copyArea() скопируем верхнюю часть экрана, ограниченную прямоугольником с началом в точке (0, hy+1), шириной appSize.width-1 и высотой appSize.height-1, в область с началом в точке (0, -hy); 2) методом g.setColor() выберем цвет фона Color.yellow; 3) нарисуем методом g.fillRect() прямоугольник с началом в точке (1, appSize.height-hy-1), шириной appSize.width-2 и высотой hy.

Далее увеличим счетчик сдвигов counter на 1, а затем проверим его. Если значение counter равно yChar+5 (то есть сдвинута полная строка), то рисуем строку с номером current в нижней части окна. Для этого: 1) сбрасываем счетчик сдвигов counter в 0; 2) если строка первая (current равно 0) то методом g.setColor() устанавливаем красный цвет, иначе - черный; 3) методом g.drawString() выводим строку с номером current в точке с координатами (10, appSize.height-10); 4) увеличиваем номер текущей рисуемой строки current на 1; 5) если нарисованы все строки (current больше или равно strs.length), то устанавливаем номер текущей рисуемой строки current в 0.

Далее выполняется задержка на 50 миллисекунд, после чего работа бесконечного цикла возобновляется с самого начала.

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