12.11.2012 12:41
 0просмотров 35 6

Динамичное создание потоков.

Я показывал, как сделать так, чтобы бот работал в многопоточном режиме. Но такое создание потоков очень не удобно. Создание даже 10-ти потоков будет долгим и нудным. А если их создать 100? Или хочется попробовать разное количество и проверить эффективность? Создавать их и удалять? Конечно, нет.
Создаём в классе HWM_PersScanner следующие поля:

Thread[] t;
int[] Start, End;
int TreadCount = 5;
int MaxID = 10000;
int MinID = 1;


Это массив, который будет содержать сами потоки, массив начальных и конечных значений для этих потоков, количество потоков, а так же минимальное и максимальное значение для бота.
Теперь создадим метод ScanAll, который будет заниматься созданием потоков. В нём сначала проинициализируем массивы по указанному числу потоков:

t = new Thread[TreadCount];
Start = new int[TreadCount];
End = new int[TreadCount];


Определяем, сколько персонажей придётся обработать одному потоку:

int step;
float f = (float)MaxID/(float)TreadCount;
if (f > (int)f) step = (int)f + 1;
else step = (int)f;


В цикле инициализируем потоки. Пусть они выполняют метод GetPart(), его созданием займёмся чуть позже. Определяем начальные и конечные значения ID для них и задаём каждому имя - его номер.

for (int i = 0; i < TreadCount; i++){
   t = new Thread(new Runnable() {
      @Override
      public void run() {
         GetPart();
      }
   });

   Start = i * step;
   End = (i + 1) * step;
   t.setName("" + i);
}

Теперь выполняем их:

for (int i = 0; i < TreadCount; i++) t.start();

И ждём их завершения:

for (int i = 0; i < TreadCount; i++) try {
    t.join();
} catch (InterruptedException ex) {;}


Метод join может сгенерировать InterruptedException, про него я уже говорил ранее.

Метод GetPart() будет определять имя текущего потока и запускать ScanDiapason:

private void GetPart(){
    int N = Integer.parseInt(Thread.currentThread().getName());
    ScanDiapason(Start[N], End[N]);
}

Теперь, чтобы работала переменная MinID изменим вызов GetPage в ScanDiapason:

GetPage("http://www.heroeswm.ru/pl_info.php?id=" + (i + MinID));

Всё. Теперь количество потоков легко изменять, меняя значение переменной TreadCount, а диапазон работы бота переменными MaxID и MinID. Осталось сделать вызов метода ScanAll в main:

HWM_PersScanner scanner = new HWM_PersScanner();
scanner.ScanAll();
Комментарии
1 / 15.11.2012 16:34 / Crag_Hack [17] ?
Пытаюсь русский текст заливать в поток, какая то хрень выходит. Че подправить?
2 / 15.11.2012 22:31 / FireSwarm [10] ?
Кодировки - это один из самых неприятных моментов.
По умолчанию java работает в юникоде - utf-8, windows руками и ногами сопротивляется и не хочет понимать его. Если просматривать результирующий файл, например, в netepad++, проблем не должно быть. Хотя тут тоже гарантий нет. Попробуй указать кодировку для потока.
File file = new File("test.csv");
PrintStream printStream = new PrintStream(file, "cp1251");
System.setOut(printStream);
3 / 16.11.2012 00:14 / Crag_Hack [17] ?
Еще вопросец, хотя понимаю что надо читать мануалы.

Как делать так, чтоб файл не создавался заново ,а в него писли с конца?

Сам знаешь, хочу посчитать все эли на руках

Просто таблица в которой указан диапазон и далее количество элей каждого типа.

+ Эти модуля добавляются руцями, а не автоматом.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;

А о них ты не упомянул.

Равно как и о исключении throws FileNotFoundException.

Все таки я хоть получайнег, имевший дело с сями.  Народ может быть в непонятках.
4 / 16.11.2012 08:23 / FireSwarm [10] ?
Цитата: Crag_Hack
+ Эти модуля добавляются руцями, а не автоматом.
Стандарты, давным давно заданные в делфях (спасибо Хейлсбергу!), работают и по сей день, поэтому руками ничего добавлять не нужно.
В теме "Hello, world!" я писал про добавление импортов, с помощью волшебной лампочки. Конечно, этого нельзя сделать в блокноте, но для этого я и рекомендовал IDE. С исключениями таже ситуация. Необработанные исключения (почти все) - синтаксическая ошибка, NetBeans помогает в решении этой проблемы. При помощи той же лампочки.

Цитата: Crag_Hack
Еще вопросец, хотя понимаю что надо читать мануалы.
Как делать так, чтоб файл не создавался заново ,а в него писли с конца?
Эту задачу легко решает BufferedOutputStream. Мануалы читать не обязательно, иначе этот блог не имел бы смысла. С помощью гугла легко можно найти готовые решения. Например такое:
        File file = new File("1.txt");
        PrintStream printStream = new PrintStream (new BufferedOutputStream(new FileOutputStream (file, true)));
        System.setOut(printStream);
5 / 16.11.2012 13:45 / Crag_Hack [17] ?
Спасибки. походу внимательность нулячья.  :Р
6 / 28.12.2012 21:41 / goshazvir [15] ?
чуваааак!!! спасибо тебе, пиши еще. Как раз учу Java, пока прочитать не успел твои записи, но завтра возьмусь:)

Возможность комментировать доступна после регистрации