Работа с потоками в java

Будем считать что уже знаем что такое поток, зачем он нам нужен, и что у нас есть задача, которую можно выполнить в несколько потоков. В моей прикладной задаче у меня есть массив адресов серверов к котороым необходимо подключиться, получить данные и записать в локальную бд. Для ускорения я подключаюсь к серверам в несколько потоков.

Код подключения и записи в бд приводить не буду, он не относиться к теме поста. Вместо этого кода я буду использовать функцию

Thread.sleep(500);

которая будет эмулировать выполнение задачи.

Для начала нужно создать класс, в котором будет код нашей задачи:

public class Job implements Runnable {
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Главное тут имплементировать интерфейс Runnable и создать метод run, в котором описана логика работы (в данном случае пауза). Так же можно создать конструктор, в который передавать дополнительные параметры. В моей прикладной задаче это были адреса серверов для подключения.

Теперь можно запустить несколько потоков на выполнение:

for (Element link : links) {
Job j = new Job();
j.run();
}

Этот код замечательно работет, но ожидается несколько проблем:

  • Если создать много потоков, то виртуальная маина java может повесить всю операционную систему
  • Т.к. в каждом потоке я подключаюсь к бд, то я могу достигнуть лимита подключений

Данные проблемы можно решить ограничив количество одновременных потоков. Для этого импортируем пару дополнительных классов:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

И немного изменим цикл, запускающий потоки:

ExecutorService pool = Executors.newFixedThreadPool(5);
for
(Element link : links) {
Job j = new Job();
pool.execute(j);
}

В этом коде создается пул потоков. Ограничение в 5 одновременных потоков. Количество одновременных потоков нужно подбирать исходя из конкретной задачи.

Теги:

java thread