Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
89
Добавлен:
24.02.2016
Размер:
202.75 Кб
Скачать

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

Все потоки в языке 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-броузеры не позволяют заменить уровни защиты.

Многопотоковая графика и двойная буферизация

Для реализации немерцающей анимации существует множество различных способов. Рассмотрим некоторые из них.

Использование методов updateиpaint

Пусть некоторый объект должен перемещаться в пределах экрана. В этом случае нет необходимости полностью очищать и перерисовывать экран. Тогда в методе paintнадо закрашивать и перерисовывать только маленькую часть экрана. Для вызова методаpaintможно использовать методrepaint. Но при этом будет перерисовываться закрашиванием фоновым цветом весь экран. Чтобы экран не закрашивался фоном, необходимо переопределить методupdate. В нем надо напрямую вызвать методpaint.

Желательно, чтобы метод paintвыполнялся как можно быстрее, потому что обычно при выполнении этого метода не реагируют на события элементы управления.

Ниже приводится пример апплета двойного назначения, в котором выполняется движение нескольких строк по области апплета.

Каждая строка затирает себя выводом в то же место, но цветом фона.

Пример 4. Бегущие строки без мигания

import javax.swing.*;

import java.applet.Applet;

import java.awt.*;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

import java.util.Vector;

public class VertScroller extends Applet implements Runnable, ActionListener{

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

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

private Vector strings;

private int count = 0;

private int height;

private int width;

private Button startButton, stopButton;

private Thread animated;

public void update(Graphics g)

{

paint(g);

}

public void init()

{

strings = new Vector();

setBackground(Color.YELLOW);

height = getSize().height;

width = getSize().width;

startButton = new Button("Начало движения");

startButton.addActionListener(this);

add(startButton);

stopButton = new Button("Останов движения");

stopButton.addActionListener(this);

add(stopButton);

}

public void actionPerformed(ActionEvent e)

{

if ( e.getSource()==startButton)

{ if(strings.size() == 0 )

{

getGraphics().clearRect(0,0,width,height);

animated = new Thread(this);

animated.start();

}

int x = randomInt(width/2);

int y = randomInt(height/2);

int deltax = 1+randomInt(10);

int deltay = 1+randomInt(10);

if(count<strs.length)

{

strings.addElement(new MyString(strs[count++],x,y,deltax,deltay));

}

else

{

strings.addElement(new MyString("Простая строка",x,y,deltax,deltay));

}

}

else

if(e.getSource()==stopButton)

{

strings.removeAllElements();

animated = null;

count = 0;

}

repaint();

}

private int randomInt(int max) {

double x = Math.floor((double)(max+1)*Math.random()) ;

return (int)(Math.round(x));

}

public void run()

{

Thread my = Thread.currentThread();

while (my == animated)

{ repaint();

try

{

Thread.sleep(100);

}

catch (InterruptedException e)

{ }

}

}

public void paint(Graphics g)

{

MyString str;

for ( int i = 0; i < strings.size(); i++)

{

str =(MyString) strings.elementAt(i);

g.setColor(getBackground());

str.draw(g);

str.move(width,height);

g.setColor(Color.BLACK);

g.setColor(getForeground());

str.draw(g);

}

}

public static void main(String[] args) {

JFrame frame = new JFrame ("Пример");

int width = 800;

int height = 300;

VertScroller appl = new VertScroller ();

appl.init();

frame.getContentPane().add(appl);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setSize(width,height);

frame.setVisible(true);

}

}

import java.awt.*;

public class MyString extends Object // класс для реализации строк

{

int x,y,deltax,deltay;

String str;

public MyString(String str, int x, int y, int deltax, int deltay) {

this.x = x;

this.y = y;

this.deltax = deltax;

this.deltay = deltay;

this.str = str;

}

public void draw(Graphics g) {

g.drawString(str,x,y);

}

public void move(int width, int height) {

x = x+ deltax;

y = y+deltay;

}

}

Конечно, код стал более сложным, но отрисовка выполняется намного быстрее.