Работа с вычислительными потоками с помощью класса Thread
Попробуем создать много вычислительных потоков, работающих вместе.
// класс потокового вычисления:
class MyTask extends Thread
{ // предполагается, что MyTask вызывается только из класса Parent
Parent main;
public MyTask(Parent main)
{
this.main = main; // вызывавший класс
setDaemon(true); // ставим демона, чтоб поток был сам себе хозяин
setPriority(Thread.NORM_PRIORITY); // устанавливаем приоритет
start(); // и запускаем поток сразу же после инициализации
}
public void run()
{
// здесь нужно разместить код, который будет работать в отделтном потоке
// для примера - for(int i = 0; i < 500; i++); // :o)
// по завершению вычислений поток сигнализирует вызвавшему классу и
//самоуничтожается (причём самоуничтожается полностью,
//так как я поставил демона при инициализации)
main.next();
// в зависимости от вида функции next(), поток может передать результаты
//работы, свой ID или что-то ещё вызвавшему его классу
}
}
// Ну вот и вызывающий класс:
class Parent
{
int started, tasks; // это глобальные переменные
public Parent()
{
tasks = 20; // максимальное количество запущеных потоков
started = 0; // количество уже запущеных потоков
// создаём нужное количество потоков
while(started < tasks) CreateTask();
// а теперь сидим и ждём, пока есть хоть один работающий поток
while(started > 0);
}
// функция вызывающаяся по завершению работы потока
// нужно заметить, что ставить синхронизацию и публичность обязательно
// в функцию может передаваться результаты работы потока,
// ID задачи и т.д.
// в данном случае функция просто поддерживает одинаковое кол-во
// работающих потоков
synchronized public void next()
{
// функция вызывается только по завершению потока,
//поэтому уменьшаем счётчик количества запущеных потоков
started --;
// и если запущеных потоков меньше tasks,
//то запускаем ещё один
if(started < tasks) CreateTask();
// только для того, чтобы этот пример не работал вечно, уменьшаем потолок
//количества запущеных потоков
tasks--;
}
// функция запуска нового потока
// тоже обязательно должна быть синхронизирована,
// Protected я добавил от себя лично :o)
synchronized protected void CreateTask()
{ // увеличиваем значение запущеных потоков
started++;
// и просто создаём новый объект, а там уже прописано,
//чтоб он стартовал...
MyTask task = new MyTask(this);
}
}