n++;
try
{
Thread.sleep (10);
synchronized (this)
{
if (waiting)
wait ();
}
}
catch(InterruptedException iE){}
}
System.out.print ("object "+num);
System.out.println (" finished ");
}
}
//-------------------------------------
class BallsCj1
{
public static void main ()
{
Ball ball1= new Ball (1); // Создать первый обычный объект
Ball ball2= new Ball (2); // Создать второй обычный объект
System.out.println("objects are working");
// Объекты функционируют 20 мс
try
{
Thread.sleep (20);
}
catch(InterruptedException iE){}
ball1.Suspend ( ); // Приостановить первый обычный объект
ball2.Suspend ( ); // Приостановить второй обычный й объект
System.out.println("objects are suspend and are resumed");
ball1.Resume ( ); // Возобновить выполнение первого объекта
ball2.Resume ( ); // Возобновить выполнение второго объекта
// Объекты функционируют 20 мс
try
{
Thread.sleep (20);
}
catch(InterruptedException iE){}
ball1.Suspend ( ); // Приостановить первый обычный объект
ball2.Suspend ( ); // Приостановить второй обычный объект
}
}
/*
Результат:
objects are working
object 1 n= 0
object 2 n= 0
object 1 n= 1
object 2 n= 1
objects are suspend and are resumed
object 1 n= 2
object 2 n= 2
object 1 n= 3
object 2 n= 3
*/
5.3.2. Этап 2. Разработка класса Balls
На этом этапе реализуем класс Balls, содержащий массив обычных объектов класса Ball и осуществляющий их одновременный запуск, а также приостановку и возобновление функционирования. Дополнительно к указателю pBall на массив обычных объектов, класс Balls содержит функции, выполняющие запуск (Start), приостановку выполнения (Suspend) и возобновление выполнения (Resume) всей совокупности обычных объектов.
Диаграмма классов Balls–приложения второго этапа изображена на рис. 5.3.2.1.
Рис 5.3.2.1. Диаграмма классов Balls–приложения второго этапа
Реализация второго этапа разработки Balls–приложения на языке C# дана в примере 5.3.2.1.
Реализация второго этапа разработки Balls–приложенияна языке Java дана в примере 5.3.2.2.
Пример 5.3.2.1. Реализация второго этапа разработки Balls–приложения на языке C#.
////////////////////
// C# File BallsCs2.cs
// Файл BallsCs2.cs полностью включает файл BallsCs1.cs, дополнив его
// нижеследующим описанием класса Balls и изменённой функцией Main
. . .
//-------------------------------------
class Balls // Класс объектов
{
Ball [] pBall;
public Balls ( )
{
pBall= new Ball [2];
for (int i= 0; i < 2; i++)
pBall[i]=new Ball (i);
Start ( );
}
//---------------
public void Start ( ) // Стартовать
{
for(int i=0; i < 2; i++)
{
pBall[i]. Start ( );
}
}
//---------------
public void Suspend ( ) // Возобновить
{
for (int i=0; i < 2; i++)
pBall[i].Suspend ( );
}
//---------------
public void Resume ( ) // Приостановить
{
for (int i= 0; i < 2; i++)
pBall[i].Resume ( );
}
};
//-------------------------------------
class BallsCs2
{
static void Main (string[] args)
{
Balls pBalls= new Balls ( ); // Создать объект класса Balls
Console.WriteLine ("Объекты функционируют");
Thread.Sleep (20); // Объект функционирует 20 мс
pBalls.Suspend ( ); // Приостановить функционирование
Console.WriteLine("Объекты приостановлены и возобновлены");
pBalls.Resume ( ); // Возобновить функционирование
Thread.Sleep (20); // Объект функционирует 20 мс
pBalls.Suspend ( ); // Приостановить функционирование
}
}
/*
Результат:
Потоковые объекты функционируют
Объект 1 n= 0
Объект 2 n= 0
Объект 1 n= 1
Объект 2 n= 1
Объекты приостановлены и возобновлены
Объект 2 n= 2
Объект 1 n= 2
Объект 1 n= 3
Объект 2 n= 3
*/
Пример 5.3.2.2. Реализация второго этапа разработки Balls–приложения на языке Java.
package BallsCj2;
////////////////////
//C# File BallsCj2
class Ball implements Runnable // Класс обычного объекта
{
int num;
Thread thread;
boolean run;
boolean waiting= false;
boolean life;
public Ball (int Num) // Конструктор
{
num= Num; life= false; run= false;
Start ( );
}
public void Start ( ) // Стартовать
{
if (!run)
{
run= true;
life= true;
thread= new Thread (this);
thread.start ( );
}
}
//---------------
synchronized public void Suspend ( ) // Приостановить
{
if (run)
{
run= false;
waiting=true;
}
}
//---------------
synchronized public void Resume ( ) // Возобновить
{
if (!run)
{
run= true;
waiting=false;
notify();
}
}
//---------------
public void run ( ) // Выполнить поток
{
int n= 0;
while (life)
{
System.out.print("object "+num);
System.out.println(" n= "+n);
n++;
try
{
Thread.sleep (10);
synchronized(this)
{
if(waiting)
wait();
}
}
catch(InterruptedException iE){}
}
System.out.print("object "+num);
System.out.println(" finished ");
}
}
//-------------------------------------
class Balls // Класс объектов
{
Ball [] pBall;
public Balls ( )
{
pBall= new Ball [2];
for (int i= 0; i < 2; i++)
pBall[i]=new Ball (i+1);
Start ( );
}
//---------------
public void Start ( ) // Стартовать
{
for(int i=0; i < 2; i++)
{
pBall[i]. Start ( );
}
}
//---------------
public void Suspend ( ) // Возобновить
{
for (int i=0; i < 2; i++)
pBall[i].Suspend ( );
}
//---------------
public void Resume ( ) // Приостановить
{
for (int i= 0; i < 2; i++)
pBall[i].Resume ( );
}
};
class BallsCj1
{
public static void main ()
{
Balls pBalls= new Balls ( ); // Создать объекты класса Balls
System.out.println("objects are working");
// Объекты функционируют 20 мс
try
{
Thread.sleep (20);
}
catch(InterruptedException iE){}
pBalls.Suspend ( ); // Приостановить объекты
System.out.println("objects are suspend and are resumed");
pBalls.Resume ( ); // Возобновить выполнение объектов
// Объекты функционируют 20 мс
try
{
Thread.sleep (20);
}
catch(InterruptedException iE){}
pBalls.Suspend ( ); // Приостановить объекты
}
}
/*
Результат:
objects are working
object 1 n= 0
object 2 n= 0
object 1 n= 1
object 2 n= 1
objects are suspend and are resumed
object 1 n= 2
object 2 n= 2
object 1 n= 3
object 2 n= 3
*/
5.3.3. Этап 3. Разработка события ev и уведомления
Включим в класс Ball обычного объекта событие ev и уведомление, сигнализирующее об очередном цикле выполнения потока. Это событие и уведомление обрабатывается функцией HandlerEv или update() класса Balls, что будет использовано при перерисовке шаров в области клиента прикладного окна на четвёртом этапе. На рис. 5.3.3.1 и в примерах 5.3.3.1 и 5.3.3.2 представлены диаграмма классов третьего этапа и программы, реализующие её.
Рис. 5.3.3.1. Диаграмма классов Balls–приложения третьего этапа
Пример 5.3.3.1. Реализация третьего этапа разработки Balls–приложения.
////////////////////
// С# File BallsCs3.cs
// Файл BallsCs3.cs полностью включает файл BallsCs2.cs, дополнив
// его объявлением события ev в классе Ball и функцией HandlerEv
// класса Balls, обеспечивающей обработку этого события.
// Изменения файла BallsCs2.cs выделены жирным шрифтом.
. . .
//-------------------------------------
delegate void delEv ( ); // Объявление типа delEv делегата события ev
class Ball
{
public event delEv ev; // Объявление события ev
. . .
//---------------
void BallFunc ( ) // Выполнить поток
{
int n= 0;
while (life)
{
Console.Write ("Объект {0}", num.ToString ( ));
Console.WriteLine (" n= {0}", n.ToString ( ));
n++;
if (ev != null) // Если событие активизировано, то
{
Console.WriteLine (" Event");
ev ( ); // свершить событие
}
Thread.Sleep (10);
}
Console.Write ("Объект {0}", num.ToString ( ));
Console.WriteLine (" завершён");
}
};
//-------------------------------------
class Balls // Класс потоковых объектов
{
Ball [] pBall;
public void HandlerEv ( ) // Обработчик события ev
{
Console.WriteLine (" HandlerEv");
}
public Balls ( ) // Конструктор
{
pBall= new Ball [2];
for (int i= 0; i < 2; i++)
{
pBall[i]=new Ball (i);
pBall[i].ev+= new delEv(HandlerEv ); // Добавить
}
Start ( );
}
. . .
}
class BallsCs3
{
static void Main (string[] args)
{
Balls pBalls= new Balls ( ); // Создать объект класса Balls
Console.WriteLine("Объекты функционируют");
Thread.Sleep (20); // Объект функционирует 20 мс
pBalls.Suspend ( ); // Приостановить функционирование
}
}
Результат:
Объекты функционируют
Объект 0 n= 0
Event
HandlerEv
Объект 1 n= 0
Event
HandlerEv
Объект 0 n= 1
Event
HandlerEv
Объект 1 n= 1
Event
HandlerEv
*/
Пример 5.3.3.2. Реализация третьего этапа разработки Balls–приложения на языке Java.
package BallsCj3;
////////////////////
//C# File BallsCj3
import java.util.*;
class Obs
{
public int num, n;
public Obs (int num, int n)
{this.num= num; this.n= n;}
int getNumber(){return num;}
int getN(){return n;}
}
class Ball extends Observable implements Runnable // Класс обычного объекта
{
int num;
Thread thread;
boolean run;
boolean waiting= false;
boolean life;
public Ball (int Num) // Конструктор
{
num= Num; life= false; run= false;
Start ( );
}
public void Start ( ) // Стартовать
{
if (!run)
{
run= true;
life= true;
thread= new Thread (this);
thread.start ( );
}
}
//---------------
synchronized public void Suspend ( ) // Приостановить
{
if (run)
{
run= false;
waiting=true;
}
}
//---------------
synchronized public void Resume ( ) // Возобновить
{
if (!run)
{
run= true;
waiting=false;
notify();
}
}
//---------------
public void run ( ) // Выполнить поток
{
int n= 0;
while (life)
{
System.out.print("object "+num);
System.out.println(" n= "+n);
n++;
// Уведомить
setChanged();
notifyObservers(new Obs(num, n));
try
{
Thread.sleep (10);
synchronized(this)
{
if(waiting)
wait();
}
}
catch(InterruptedException iE){}
}
System.out.print("object "+num);
System.out.println(" finished ");
}
}
//-------------------------------------
class Balls implements Observer // Класс объектов
{
Ball [] pBall;
public Balls ( )
{
pBall= new Ball [2];
for (int i= 0; i < 2; i++)
{
pBall[i]=new Ball (i+1);
pBall[i].addObserver(this);
}
Start ( );
}
//---------------
public void Start ( ) // Стартовать
{
for(int i=0; i < 2; i++)
{
pBall[i]. Start ( );
}
}
//---------------
public void Suspend ( ) // Возобновить
{
for (int i=0; i < 2; i++)
pBall[i].Suspend ( );
}
//---------------
public void Resume ( ) // Приостановить
{
for (int i= 0; i < 2; i++)
pBall[i].Resume ( );
}
public void update (Observable r, Object ob) // Обработчик события ev