У меня есть программа, которая сортирует большие файлы, разбивая их на куски, сортируя куски и объединяя их в окончательный отсортированный файл. Приложение запускает один поток для загрузки / сохранения данных из / в файл - только один поток выполняет операции ввода-вывода. Также есть еще два потока, которые получают данные чанка, сортируют их и затем отправляют отсортированные данные обратно в поток, который выполняет ввод / вывод.
Таким образом, в целом работают 4 потока - основной поток, поток, который загружает / сохраняет данные, и два потока, которые сортируют данные.
Я думал, что во время выполнения я увижу 1 спящий поток (основной), который не требует времени ЦП, и 3 активных потока, которые используют 1 ядро ЦП каждый.
Когда я запускаю эту программу на двухъядерном 6-ядерном процессоре с гиперпоточностью (24 процессора), я вижу, что ВСЕ 24 процессора загружены на 100%!
Первоначально я думал, что алгоритм сортировки является многопоточным, но после изучения источников Java я обнаружил, что это не так.
Я использую простой Collections.sort (LinkedList) для сортировки данных ...
вот некоторые подробности:
# java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
# uname -a
Linux 2.6.32-28-server #55-Ubuntu SMP Mon Jan 10 23:57:16 UTC 2011 x86_64 GNU/Linux
Я использовал nmon для мониторинга загрузки процессора.
Буду признателен за любое объяснение этого случая и за любые советы о том, как контролировать загрузку ЦП, поскольку эта конкретная задача не оставляет времени ЦП для других приложений.
[ОБНОВЛЕНО]
Я использовал jvisualvm для подсчета потоков - он показывает только те потоки, о которых я знаю. Также я создал простую тестовую программу (см. Ниже), которая запускает только один основной поток и дает точно такие же результаты - все 24 процессора заняты почти на 100% во время выполнения кода
public class Test {
public void run(){
Random r = new Random();
int len = r.nextInt(10) + 5000000;
LinkedList<String> list = new LinkedList<String>();
for (int i=0; i<len; i++){
list.add(new String("test" + r.nextInt(50000000)));
}
System.out.println("Inserted " + list.size() + " items");
list.clear();
}
public static void main(String[] argv){
Test t = new Test();
t.run();
System.out.println("Done");
}
}
[UPDATE]
Вот снимок экрана, который я сделал при запуске программы выше (использовал nmon):
http://imageshack.us/photo/my-images/716/cpuload.png/