многопоточность сети java

#java #multithreading #network-programming #threadpool

#java #многопоточность #сетевое программирование #пул потоков

Вопрос:

Я пытаюсь создать сервер, который может одновременно принимать файлы от нескольких клиентов.

Но он отправляет файлы последовательно, и я не понимаю, почему….

Кто-нибудь может помочь? Спасибо

Я публикую свой фрагмент из двух потоков. каждый раз, когда я принимаю соединение, я создаю экземпляр класса отправки и выполняю их.

 This is main thread that accepts connections
int poolSize = 1; 
    int maxPoolSize = 3;
    long keepAliveTime = 10;
    ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(5);
    threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
  

Комментарии:

1. то, что вы подразумеваете под «И кажется, что «ClientServer.accept()» блокирует». это должен быть блокирующий вызов, и он должен ждать, пока клиент не подключится к серверу. Вы устанавливаете тайм-аут для объекта ClientServer?

2. это выглядит нормально, что заставляет вас думать, что оно не работает параллельно? В качестве примечания, если вы запустите это под tomcat, клиенты могут отправлять файлы через http post, и вы получаете все это бесплатно.

3. Вы отправляете файлы одновременно? Используете ли вы всю пропускную способность сети только с одним подключением?

4. Какая часть вашей программы занимает много времени? Прямо сейчас практически единственное, что делает отправка, — это регистрирует все, и это делается внутри блокировки, поэтому неудивительно, что это не происходит одновременно. В этом вся цель блокировки … Кстати, почему бы вам не использовать synchronized(lock) { … }?

5. Похоже, вы отредактировали свои фрагменты кода и удалили большую часть соответствующего кода. Это значительно усложнит понимание приведенных ниже ответов будущим читателям этого вопроса. Могу ли я предложить, если вы хотите получить новые комментарии к тому, где находится ваш код после работы над ним, добавить его в старые фрагменты или создать новый вопрос. 🙂

Ответ №1:

Блокировка в методе run() класса Submission приводит к тому, что эта часть вашего кода выполняется последовательно. Эта блокировка передается через конструктор, поэтому она распределяется между всеми вашими дочерними элементами, поэтому все они вызывают lock.lock() перед запуском stats.logSubmission. Это означает, что только один поток одновременно будет вызывать logSubmission.

В качестве быстрого способа добиться этого одновременно; попробуйте снять блокировку и вместо того, чтобы сразу записывать в файлы, попробуйте сохранить записи журналов в concurrentlink Queue . Затем вы можете сбросить их на диск в какой-то более поздний момент выполнения или при некоторых условиях (размер, время, ..). Эта очередь не блокируется, быстра и потокобезопасна.

Ответ №2:

По сути, вам нужно разделить поток .accept() , в котором вы устанавливаете новые соединения, и где вы обрабатываете эти запросы.

Каждый раз, когда вы вызываете .accept() сокет сервера, порождайте новый поток для обработки этого запроса и передавайте в этот поток соединение с сокетом из .accept() метода.