Мне нужно создать пул работников на Java, где каждый рабочий имеет свой собственный подключенный сокет; когда рабочий поток работает, он использует сокет, но сохраняет его открытым для повторного использования позже. Мы решили использовать этот подход, поскольку накладные расходы, связанные с созданием, подключением и уничтожением сокетов на разовой основе, потребовали слишком много накладных расходов, поэтому нам нужен метод, с помощью которого пул работников предварительно инициализируется их сокетным соединением, готовым к приступайте к работе, сохраняя ресурсы сокетов в безопасности от других потоков (сокеты не являются потокобезопасными), поэтому нам нужно что-то в этом направлении...
public class SocketTask implements Runnable {
Socket socket;
public SocketTask(){
//create + connect socket here
}
public void run(){
//use socket here
}
}
При запуске приложения мы хотим инициализировать рабочих и, надеюсь, сокет-подключения так или иначе...
MyWorkerPool pool = new MyWorkerPool();
for( int i = 0; i < 100; i++)
pool.addWorker( new WorkerThread());
Поскольку работа запрашивается приложением, мы отправляем задачи в рабочий пул для немедленного выполнения...
pool.queueWork( new SocketTask(..));
Обновлено с помощью рабочего кода
Основываясь на полезных комментариях от Gray и jontejj, у меня есть следующий код, работающий...
SocketTask
public class SocketTask implements Runnable {
private String workDetails;
private static final ThreadLocal<Socket> threadLocal =
new ThreadLocal<Socket>(){
@Override
protected Socket initialValue(){
return new Socket();
}
};
public SocketTask(String details){
this.workDetails = details;
}
public void run(){
Socket s = getSocket(); //gets from threadlocal
//send data on socket based on workDetails, etc.
}
public static Socket getSocket(){
return threadLocal.get();
}
}
ExecutorService
ExecutorService threadPool =
Executors.newFixedThreadPool(5, Executors.defaultThreadFactory());
int tasks = 15;
for( int i = 1; i <= tasks; i++){
threadPool.execute(new SocketTask("foobar-" + i));
}
Мне нравится этот подход по нескольким причинам...
- Сокеты - это локальные объекты (через ThreadLocal), доступные для выполняемых задач, устраняющие проблемы параллелизма.
- Сокеты создаются один раз и сохраняются открытыми, повторно используются при постановке новых задач, исключая создание или уничтожение служебных данных сокета.