2013-12-07 2 views
0

Привет, я создаю сеть Peer2Peer, используя сокет UDP, каждый раз, когда сервер получает сообщение от клиента, он создает поток для обработки запроса.am, пытающегося реализовать очередь ThreadPool для хранения запроса и ограничения количество потоков, выполняемых на машине, и всякий раз, когда поток свободен, мы получаем потоки из очереди (Producer/Consumer), я пробовал какое-то время, но новые потоки не добавляются в очередь, заканчивающуюся только в конце добавлен первый поток. Многопоточный UDP-сервер с использованием ThreadPool

 
    public void run() {

BlockingQueue<Runnable> queue=new LinkedBlockingQueue<Runnable>(10); ExecutorService tpes =Executors.newFixedThreadPool(10); int server_port = 8767; DatagramSocket s = null; while(true){ byte[] message = new byte[1024]; DatagramPacket p = new DatagramPacket(message, message.length); try{ s = new DatagramSocket(server_port); }catch (SocketException e) { e.printStackTrace(); System.out.println("Socket excep"); } try { s.receive(p); queue.put(new RequestHandler(p)); tpes.execute(queue.take()); }catch (Exception e) { e.printStackTrace(); System.out.println("IO EXcept"); } finally{ s.close(); } } }

Я не знаю, где пойдет не так? любая помощь была бы оценена

+0

Этот метод запуска один из 'RequestHandler'? Вы создаете странную рекурсию. Также, если вы '.take()' объект, который вы только что положили там несколько строк ранее, вы могли бы просто использовать его напрямую. – zapl

+0

метод run не принадлежит RequestHandler, он является частью peerNode, который может действовать как сервер в прогоне, я слушаю запрос, и я создаю поток, а класс RequestHandler заботится обо всем остальном. Я не хочу использовать объект напрямую, потому что я буду создавать много потоков (1 поток на запрос). Я хочу использовать очередь и хранить потоки и использовать фиксированное количество потоков. – Mero

ответ

2

Вам не нужен Queue. ExecutorService имеет очередь для задач. Я также предлагаю не открывать новый сокет каждый раз, так как вы можете повторно использовать их.

Итоговый код может выглядеть примерно так.

public void run() { 
    ExecutorService tpes = Executors.newFixedThreadPool(10); 
    int server_port = 8767; 
    DatagramSocket s = null; 
    try { 
     s = new DatagramSocket(server_port); 
     while (true) { 
      byte[] message = new byte[1024]; 
      DatagramPacket p = new DatagramPacket(message, message.length); 
      try { 
       s.receive(p); 
       tpes.execute(new RequestHandler(p)); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } catch (SocketException e) { 
     e.printStackTrace(); 
     System.out.println("Socket excep"); 
    } finally { 
     if (s != null) s.close(); 
    } 
} 

RequestHandler будет работать на одной из 10 нитей, и если вы получите больше запросов, чем 10 потоков может обрабатывать вы будете иметь очередь ожидающих RequestHandler задач в рамках Executor.

Примечание: я не думаю, что имеет смысл запускать RequestHandler в пуле потоков. Обработка 1 кбайт данных невелика и, например, запись этих данных на жесткий диск происходит быстрее, чем вы можете получить пакеты. (если вы не на волокне, а ваш жесткий диск очень медленный).

+0

Я следил за вашими предложениями, но это не решило проблему, метод запуска использует тот же сокет, этот метод является частью класса PeerNode, поэтому всякий раз, когда создается экземпляр узла, он будет прослушивать тот же порт.the requestHandler получает пакет и обрабатывать его и отправлять ответ обратно клиенту на основе содержимого пакета, и все это выполняется локально, поскольку это всего лишь упражнение. идея заключается в создании поисковой системы peer2peer, где каждый узел индексирует часть сети. – Mero

+0

@Mero well udp является «без установления соединения», и при получении пакета нет понятия специального соединения. Они всего лишь простые пакеты для порта, и вы отвечаете отправителю. Или нет. Нет ничего, что было бы «связано», которое вам нужно было бы «отключить». Не знаю, как построить такую ​​сеть P2P. – zapl

+0

, каждый узел имеет Node_id и сохраняет список других идентификаторов узлов, как и до тех пор, пока вы знаете идентификатор, порт и IP (локальный хост), в этом случае вы можете поговорить с определенным узлом в сети. это подход, который я принимаю – Mero

Смежные вопросы