2015-07-28 3 views
6

Я кодирую сервер сокета Java, который подключается к Arduino, который, в свою очередь, отправляет и принимает данные. Как показано в документации к сокету Java, я настроил сервер, чтобы открыть новый поток для каждого подключения.Отправить данные из нескольких потоков в один поток

Мой вопрос: как я могу отправить данные из потоков сокетов в основную тему? Сокет будет постоянно открыт, поэтому данные должны быть отправлены во время работы потока. Любое предложение?

Обновление: цель сервера - отправить команды в Arduino (то есть включить или выключить) и получить данные от датчиков, поэтому мне нужен способ получить эти данные от датчиков, подключенных к индивидуальным потоки и отправить их в один.

+2

Я бы порекомендовал включить некоторые из вещей, которые вы уже пробовали - в отличие от простого поиска решения. Также, что касается вашего вопроса, есть ряд обучающих программ в Интернете именно для того, что вы ищете. Я посмотрю, смогу ли я быстро найти его для тебя. – Sh4d0wsPlyr

+0

Нуждается в уточнении. Я не получил, что такое клиент и что такое сервер. – voho

+0

Какие данные необходимо обменивать (отправлять) в основной поток? Потоки сокетов отправляют данные в сокет, который им принадлежит, поэтому ему не нужно отправлять данные в основной поток, чтобы отправить его клиенту. –

ответ

3

Совместное использование данных между потоками всегда сложно. Нет «правильного» ответа, все зависит от вашего варианта использования. Я полагаю, вы не ищете самую высокую производительность, но для простоты использования, не так ли?

В этом случае я бы рекомендовал посмотреть синхронизированные коллекции, карты, списки или очереди. Один класс, который кажется вам подходящим, - ConcurrentLinkedQueue.

Вы также можете создавать синхронизированные прокси для всех обычных коллекций, используя фабричные методы в классе Collections:

Collections.synchronizedList(new ArrayList<String>()); 

Вы не должны синхронизировать доступ к ним.

Другой вариант, который может быть излишним, использует базу данных. Есть некоторые базы данных в памяти, такие как H2.

В любом случае, я предлагаю вам снизить объем общей информации до минимально возможного уровня. Например, вы можете хранить «сырые» данные отдельно для каждого потока (например, в переменных ThreadLocal), а затем просто синхронизировать во время агрегации.

0

Кажется, у вас есть правильная идея - вам нужна нить для запуска подключения к внешнему устройству, и вам нужен основной поток для запуска вашего приложения.

Как вы обмениваетесь данными между этими потоками: это вообще не проблема - разные потоки могут записывать в одну и ту же память; в пределах одних и тех же потоков приложений общий объем памяти.

Что вы, вероятно, хотите избежать, это два потока, которые одновременно меняются или читают данные. Java предоставляет очень полезное ключевое слово - синхронизированное - для обработки такой ситуации, которая прямолинейна в использовании и предоставляет необходимые вам гарантии , This is a bit technical, но обсуждает возможности параллелизма.

0

Вот учебник, в котором вы можете получить дополнительную информацию. Обратите внимание: быстрый поиск в Google приведет к большому количеству ответов на ваш вопрос.

http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html

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

Также в качестве справочной информации для крупномасштабных программ не рекомендуется запускать нить для каждого соединения. Он работает отлично в меньших масштабах (например, несколько клиентов), но плохо масштабируется.

+0

Спасибо за ссылку, но у потоков нет конкретной задачи, которая может быть запущена, а затем закрыта, моя цель состояла бы в том, чтобы держать их всегда связанными, так как данные также должны быть отправлены им. –

0

Если это веб-приложение, и вы просто покажете текущее считывание любого из датчиков, то блокировка очереди будет огромным overkill и вызовет больше проблем, чем решает. Просто используйте переменное статическое поле требуемого типа. Само поле может быть статическим или может находиться в одном объекте, или оно может быть частью контекста, переданного работнику.

в SharedState классе:

static volatile float temperature; 

в теме:

SharedState.temperature = 13.2f; 

В веб-интерфейс (предполагающей JSP):

<%= SharedState.temperature %> 

кстати: если вы хотите получить доступ последние 10 отсчетов, то это также легко: просто сохраните массив с последними 10 показаниями вместо одного значения (j ust не модифицирует то, что находится внутри массива, вместо этого замените весь массив - иначе могут возникнуть проблемы синхронизации).

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