В/в данных в Java поток ориентирован. Абстракцию, которая производит или потребляет информацию., страница 2

Результат:

Начальный размер массива a1 :0

Содержимое a1 : [СТ, К, A, DЛД , F).

Чтобы получить элементы из коллекции, например, для суммирования, можно использовать метод toArrag, по схеме:

Object ia [ ] = a1.toArrag ( )

и просуммировать, например, следующим образом

int sum = 0

for (I=0  i<ia.lenth  i+i)

sum += ((integer ) ia [i] ). Int Value ( )

//содержимое коллекции не может хранить примитивные типы (int )

в коллекции создаются и хранятся объекты типа Intere.

Метод toArray ( ) – формирует массив, элементы приводятся  к типу Interer, затем значения суммируются.

Однопотоковые параллельные сервера (псевдопараллельность)

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

Многопотоковая параллельность в одном адресном пространстве организуются сонеты , для каждого потока, которые обслуживаются процессором, например, на основе квантования времени.

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

В основе работы однопотокового параллельного сервера лежит использование   асинхронного в/в, организованного с помощью Selekt  операционной системы.

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

Алгоритм работы псевдопараллельного сервера.

  1. Создать сонет и привязать его к порту службы. Добавить сокет к списку сокетов, через которые может осуществляться в/в (списку обслуживаемых сокетов).
  2. Использовать функцию Select  для получения информации о готовности сокетов к в/в.
  3. Если готов первоначальный  (ведущий) сокет, привязанный к служебному порту, то выполнить accept для получения очередного запроса на установление соединения и добавить сокет к списку обслуживаемых.
  4. Если готов для обработки (получены данные) сокет, отличный от первоначального использовать функцию  recv read для получения очередного запроса из сети, сформировать ответ и передать клиенту, используя send или write
  5. Продолжить алгоритм с этапа 2.

Фактически используется 1 поток который выполняет обязанности ведущего и ведомых потоков.

Сервер передает набор дискретно……..сокетов функции select в качестве параметров и ожидает активизации одного из них.

Выполнение потока начинается с открытия пассивного сокета на общепринятый порт. Затем при помощи макрокоманд создается битовый вектор, соответствующий дескрипторам сокетов, которые должны контролировать в select.

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

Если готов дескриптор  ведущего сокета вызывается accept для организации нового соединения, если готов (не равен 0) какого-то из неведущих дискрипторов,  то вызывается, например, служба. В которой выполняются     read для получения данных из соединения, выполняется обработка и write для отправки данных. Если передается  признак конца файла сервер закрывает дескриптор.                                                                                                                        


Хотя методы put ( )  и get ( ) класса ….синхронизированы, ничто не останавливает производителя от переполнения  потребителя, так же, как ничто не будет останавливать потребителя от потребления одного и того же значения очереди дважды. Таким образом, вы получаете следующий ошибочный вариант (точный вывод будет меняться в зависимости от быстродействия процессора и загруженности задачами):

Отдано :1

Получено: 1

Получено: 1

Получено: 1

Получено:1

Получено: 1

Отдано: 2

Отдано: 3

Отдано: 4

Отдано: 5

Отдано: 6

Отдано: 7

Получено: 7

Заметьте, что после выдачи производителем первого элемента (1 ) потребитель запускается и получает ту же 1 пять раз (это видно в последовательных строчках вывода). Затем производитель возобновляет работу и производит элементы от 2 до 7, не оставляя потребителю шансов для их потребления.

Для получения корректной версии этой программы необходимо использовать методы wait ( ) и notify ( ), чтобы сигнализировать в обоих направлениях, как показано ниже:

Корректная реализация поставщика и потребителя

Class...

Int n;

Boolean valueSet = false;

Synchronized int get ( ) {

if (! valueSet)

try {

wait (  );

}  catch (InterruptedException t) {

System.out.println (“Получено:  « +  n);

Valueset = false;

notify ( ) ;

return n ;

}

synchronized void put (int n) {

if (valueSet)

try {

wait (  );

} catch (InterruptedException выброшено») ;

}

this.n = n

valueSet  = true;

System.out.println («Отдано:  + n) ;

notify ( );

}

class Producer implements Runnable {

.....

Producer  (.....) {

this.Q. q = q ;

new Thread (this, «Producer»). Start (  );

}

public void run ( )  {

int i = 0 ;

while (true) {

q.put (i++);

}

}

}

class Consumer imlements Runnable {

Q q ;

this.q = q;

new Tread (this, «Consumer» ). Start ( );

}

public void run ( ) {

while (true) {

q.get (  );

}

}

}

class PCFixed {

public static void main (String arqs [ ] ) {

Q q = new Q ( ) ;

new Producer (q);

new Consumer (q);

System.out.println (Для прерывания нажмите Сontrol-C.»);

}