public class GenDemo extends Applet

{

Gen<Integer> iOb;

Gen<String> strOb;

public void init()

{

int i=Integer. parseInt(getParameter("intParam"));

iOb=new Gen<Integer>(i);

String s=getParameter("strParam");

strOb=new Gen<String>(s);

}

public void paint(Graphics g)

{

iOb. showType(g, 10,10);

strOb. showType(g, 30,10);

}

class Gen<T>

{

// объявление настраиваемого класса Gen

...

}

}

Итак, в апплет передается два параметра. Один из них – целое число, другой – символьная строка. Для хранения этих данных в классе GenDemo объявляются ссылки на объекты типов Gen<Integer> и Gen<String>. Типы данных Integer и String в данном случае являются параметрами настраиваемых типов. При создании первой ссылки параметру T класса Gen присваивается значение Integer. Это значит, что генерируется реализация класса Gen для работы с целыми числами и iOb является объектом именно этого класса. Во втором случае аналогичная работа проводится со значением типа String и объектом strOb. Далее при работе с объектом iOb везде, где упоминался тип Т в классе Gen используется тип Integer, а при работе с объектом strOb тип Т становится типом String.

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

НЕ нашли? Не то? Что вы ищете?

Приложение 4. Работа с JDK в режиме командной строки

Бывают ситуации, когда с пакетом JDK приходится работать непосредственно из командной строки, минуя какие-либо графические оболочки. Для этого операционную систему необходимо предварительно настроить. Эта настройка производится один раз. Рассмотрим правила настройки для самой распространенной в настоящее время операционной системы – Windows XP.

Операционная система должна иметь информацию, какой каталог JDK содержит программы, нужные для компиляции и запуска апплетов и приложений. Поэтому следует настроить переменную среды Path. Для этого выполните следующие действия.

·  Выберите "Пуск""Панель управления""Администрирование""Управление компьютером" и в левой части окна щелкните правой кнопкой мыши по строке "Управление компьютером".

·  В появившемся контекстном меню выберите пункт "Свойства", затем в окне свойств перейдите на закладку "Дополнительно".

·  В группе "Переменные среды" нажмите на кнопку "Параметры".

·  В списке "Системные переменные" выберите переменную Path и нажмите на кнопку "Изменить".

·  В текстовом поле "Значение переменной" добавьте точку с запятой и полное имя каталога BIN пакета JDK. Например, если JDK установлен в каталог D:\jdk1.4, то это имя будет выглядеть как D:\jdk1.4\bin. Соответственно, если переменной Path в списке не было, тогда ее требуется создать, и в этом случае точку с запятой в значении переменной указывать не надо.

Теперь можно работать с командной строкой. Выберите "Пуск""Выполнить", наберите и выполните команду cmd. Появится черное окно командной строки – окно DOS, в котором указывается строка приглашения в виде имени текущего каталога. В этом окне можно выполнять команды только в текстовом режиме. Для вывода списка стандартных команд наберите help и нажмите Enter. Чаще всего приходится использовать команды перемещения по каталогам, например:

d: – переход к диску D;

cd .. – переход к родительскому каталогу;

cd MyJava – переход к подкаталогу MyJava текущего каталога (относительная ссылка);

cd d:\MyJava – переход к подкаталогу MyJava диска D (абсолютная ссылка).

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

Теперь перейдем к работе с JDK. Предположим, мы хотим откомпилировать какой-то апплет. Сначала следует перейти в каталог, в котором находится java-файл этого апплета. Для компиляции используется программа javac:

javac FirstApplet. java

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

Теперь мы хотим просмотреть результат работы апплета. Для этого служит команда appletviewer.

appletviewer FirstApplet. html

Обратите внимание, что в качестве параметра в этой команде указывается html-файл. После выполнения этой команды будет выведено отдельное окно с запущенным апплетом (Kawa использует то же самое окно для запуска апплетов).

Для компиляции приложений используется та же команда javac, что и для апплетов, например,

javac ChatServer. java

А запуск приложений выглядит несколько по-другому. Для этого служит команда java. Например:

java ChatServer

Регистр символов в названии класса является существенным! Запустите эту команду на выполнение. Вы получите сообщение:

Exception in thread "main"

java. lang. NoClassDefFoundError: ChatServer

Данное сообщение означает, что java-машина не находит файл ChatServer.class, хотя он и находится в текущем каталоге. Для исправления этой ошибки следует вернуться к настройке переменных среды и создать переменную Classpath. Эта переменная указывает, где java-машина должна искать нестандартные классы. В качестве значения переменной укажите символ "." – это соответствует текущему каталогу.

Таким же образом подключаются и другие нестандартные классы, например, пакет для работы с mysql. Пусть он называется mysql-connector-java-3.0.8-stable-bin. jar и находится в каталоге C:\mysql. Для использования этого пакета в значение переменной Classpath через точку с запятой добавьте строку C:\mysql\mysql-connector-java-3.0.8-stable-bin. jar.

Обратите внимание, что при работе с окном командной строки русские символы выводятся в кодировке DOS, поэтому, например, кодировка Win1251 в этом окне будет нечитаемой.

Приложение 5. Коды примеров

Пример 1. Приложение, использующее потоки.

class WalkmanHire {

/* Прокат плееров-экскурсоводов J M Bishop Январь 1997

* Программа имитирует прокат плееров для посетителей музея.

* Имеется некоторое фиксированное количество плееров и не-

* сколько служащих, которые их выдают посетителям под денежный

* залог и принимают обратно с возвратом залога.

* По умолчанию имеется 50 плееров и 3 сотрудника. Эти значения

* можно изменить, если запустить программу с параметрами, на-

* пример,

* java WalkmanHire 100 8.

* Изначально сумма полученного залога равна 0.

* Иллюстрируют применение синхронизации, а также

* использование методов wait и notify.

* В программе одновременно используются потоки двух разных

* типов – класс мГруппа посетитителей" и класс "Сотрудник"

*/

public static void main (String [] args) {

// получение числа плееров, начало имитации

// деятельности музея

if (args. length >= 1)

pool = Integer. parseInt(args[0]);

else pool = 50;

Museum m = new Museum (pool);

// получение количества сотрудников,

// создание и запуск потоков для имитации работы сотрудников

if (args. length >= 2)

helpers = Integer. parseInt(args[1]);

else helpers = 3;

for (int i=0; i<helpers; i++)

new Counter (m, i).start();

}

static int pool;

static int helpers;

}

import java. io.*;

class Museum {

Museum (int w) {

walkmen = w;

cash = 0;

}

synchronized void hire (int c, int n) {

// Если недостаточно свободных плееров,

// ждать, пока не будет произведен возврат количества,

// необходимого для текущей группы посетителей

System. out. println("Сотруднику "+c+" требуется "+n+

" плееров");

while (walkmen < n) {

try { wait(); }

catch (InterruptedException e) {}

}

// Выдать плееры и принять залог.

// Пробудить следующий поток, находящийся в состоянии

// ожидания.

walkmen -= n;

cash += n;

System. out. println("Сотрудник "+c+" выдал "+n+" плееров");

System. out. println("Текущее состояние:"+

" Залог: "+cash+" Всего: "+(walkmen+cash)

+ " Плееры в наличии: "+walkmen);

notify ();

}

synchronized void replace (int n) {

// Принять плееры, вернуть залог и пробудить следующий

// поток, находящийся в состоянии ожидания

System. out. println("Возвращено "+n+" плееров");

walkmen +=n;

cash -= n;

notify ();

}

private static int walkmen;

private static int cash;

}

class Visitors extends Thread {

Visitors (Museum m, int w) {

museum = m;

groupSize = w;

}

public void run () {

// Группа осматривает экспозицию музея в течение случайного

// интервала времени (от 1 до 2 секунд), затем возвращает

// плееры и покидает музей.

// Поток "Группа посетителей" уничтожается.

try {sleep((int) (Math. random()*1000)+1);} catch(InterruptedException e) {}

museum. replace(groupSize);

}

Museum museum;

int groupSize;

}

class Counter extends Thread {

Counter (Museum m, int q) {

museum = m;

queue = q;

}

public void run () {

// Генерируется количество посетителей в новой группе,

// выдается нужное количество плееров,

// создается и запускается объект-поток

// для группы посетителей.

while (true) {

int w = a(7);

museum. hire(queue, w);

new Visitors (museum, w).start();

// Генерируется пауза перед приходом

// следующей группы посетителей

try {sleep(a(100));} catch(InterruptedException e) {}

}

}

Museum museum;

int queue;

static int a (int x) {

return (int) (Math. random() * x) +1;

}

}

Пример 2. Два потока, соединенные каналом ввода-вывода. Один поток рисует фейерверк, другой формирует для него цвет

/* Апплет, иллюстрирующий обмен данными с помощью каналов ввода-

* вывода. Апплет производит рисование залпов фейерверка.

* Рисованием фейерверка занимается объект-поток типа

* ZalpThr. Другой поток (типа ColorThr) случайным образом

* генерирует цвет очередной серии залпов.

* Для передачи сгенерированного цвета в объект-поток рисования

* фейерверка используются канальные потоки ввода-вывода,

* которые создаются в объекте-апплете.

*/

import java. awt.*;

import java. applet.*;

import java. io.*;

// класс рисования фейерверка

public class Zalp extends Applet

{

// канальный поток ввода (для чтения сгенерированного цвета)

PipedInputStream in=null;

// канальный поток вывода (для передачи сгенерированного цвета)

PipedOutputStream out=null;

public void init()

{

// создание канальных потоков ввода-вывода

try

{

in = new PipedInputStream();

// поток вывода создается на основе потока ввода

// для организации коммуникационного канала

// между ними

out = new PipedOutputStream(in);

}

catch(IOException ex)

{

}

setBackground(Color. black);

// создание потока рисования фейерверка,

// в качестве параметров конструктора передаются

// поток ввода для получения цвета рисования и

// графический контекст апплета

new ZalpThr(in, getGraphics()).start();

// создание потока генерации цвета фейерверка,

// в качестве параметров конструктора передается

// поток вывода для передачи цвета

new ColorThr(out).start();

}

}

import java. io.*;

// поток генерации цвета фейерверка

class ColorThr extends Thread

{

PipedOutputStream out;

ColorThr(PipedOutputStream out)

{

this. out=out;

}

public void run()

{

while (true)

{

try

{

// генерация компонентов цвета и отправка

// их через канал вывода потоку рисования

// фейерверка

out. write(100+(int)(Math. random()*155));

out. write(100+(int)(Math. random()*155));

out. write(100+(int)(Math. random()*155));

}

catch(IOException ex)

{

}

try

{

// задается пауза до генерации

// следующего цвета

sleep((int)(Math. random()*10000));

}

catch(InterruptedException e)

{ }

}

}

}

import java. awt.*;

import java. io.*;

// класс рисования фейерверка

class ZalpThr extends Thread

{

int M=300,N=300;

int zx, zy;

int zd;

boolean znew=true;

int r, g,b;

PipedInputStream in=null;

Graphics gr;

ZalpThr(PipedInputStream in, Graphics gr)

{

this. in=in;

this. gr=gr;

}

public void run()

{

while (true)

{

if (znew)

{

zx=(int)(Math. random()*M);

zy=(int)(Math. random()*N);

zd=0;

znew=false;

// проверяем наличие данных в потоке ввода

// если они там есть, то считываем их

try

{

if (in. available()>0)

r=in. read();

if (in. available()>0)

g=in. read();

if (in. available()>0)

b=in. read();

}

catch(IOException ex)

{

System. out. println("Exception!!!");

}

}

else

{

zd+=10;

if(zd>=M)

znew=true;

}

paint();

try

{

sleep(50);

}

catch(InterruptedException e)

{

}

}

}

public void paint()

{

int x, y;

int d;

Color col=new Color(r, g,b);

gr. setColor(col);

gr. clearRect(0,0,M, N);

if (zd==0)

{

gr. fillOval(zx, zy,10,10);

}

else if (zd<=M/2)

{

double dvaPI=2*Math. PI;

double step=dvaPI/100;

for (double i=0; i<dvaPI; i+=step)

{

d=zd/2+(int)(Math. random()*zd/2);

x=zx+(int)(d*Math. cos(i));

y=zy-(int)(d*Math. sin(i));

gr. fillOval(x, y,5,5);

}

}

}

}

Пример 3. Чат-сервер

/* Чат-сервер J M Bishop Январь 1997

* Модифицированная версия - Java 1.1 Январь 1998

* Создает сервер для обмена сообщениями.

*

* Подключение клиента:

* telnet x y

* где x и y - имя и порт компьютера,

* на котором запущен сервер.

*

* Иллюстрирует сокеты, ввод-вывод на сокетах

* потоки, синхронизацию и использование списков.

*/

import java. io.*;

import .*;

public class ChatServer {

private static List clientList = new List();

private static int id = 0;

public static void main(String[] args) throws IOException {

// Назначаем порт и создаем сокет.

int port = 8190;

if (args. length > 0)

port = Integer. parseInt(args[0]);

ServerSocket listener = new ServerSocket(port);

System. out. println("The Chat Server is running " +

" on port "+port);

// Ожидаем (слушаем) новых клиентов.

// Для каждого клиента создаем поток-обработчик.

// Добавляем клиента в связный список.

while (true) {

Socket client = listener. accept();

new ChatHandler(client).start();

System. out. println("New client no."+id+

" from "+ client. getInetAddress()+

" on client's port "+client. getPort());

clientList. reset();

clientList. add(client);

id++;

}

}

static synchronized void broadcast

(String message, String name)

throws IOException {

// Посылаем сообщение всем клиентам.

Socket s;

PrintWriter p;

for (clientList. reset();

!clientList. eol(); clientList. succ())

{

s = (Socket)clientList. current();

p = new PrintWriter(s. getOutputStream(), true);

p. println(name+": "+message);

}

}

static synchronized void remove(Socket s) {

// Ищем клиента в списке (по ссылке на его сокет)

// и удаляем его из списка.

Socket t;

for (clientList. reset();

!clientList. eol(); clientList. succ())

{

t = (Socket)clientList. current();

if (t. equals(s))

break;

}

clientList. remove();

id--;

}

}

class ChatHandler extends Thread {

// Класс ChatHandler вызывается из ChatServer:

// один поток для каждого клиента, подключившегося к чату.

private BufferedReader in;

private PrintWriter out;

private Socket toClient;

private String name;

ChatHandler(Socket s) {

toClient = s;

}

public void run() {

try {

// Создаем потоки ввода-вывода для сокета

// и печатаем приглашение.

in = new BufferedReader(new InputStreamReader(

toClient. getInputStream()));

out = new PrintWriter(toClient. getOutputStream(),

true);

out. println("*** Welcome to the Chatter ***");

out. println("Type BYE to end");

out. println("What is your name? ");

out. flush();

String name = in. readLine();

ChatServer. broadcast(name+

" has joined the discussion.", "Chatter");

// Читаем строки сообщения

// и отправляем сообщение всем клиентам.

while (true) {

String s = in. readLine().trim();

// Проверяем первые три символа для BYE.

// Избегаем проблем с разными символами конца строки.

if (s. length() > 2 && s. charAt(0) == 'B' &&

s. charAt(1) == 'Y' && s. charAt(2) == 'E') {

ChatServer. broadcast(name+

" has left the discussion.","Chatter");

break;

}

ChatServer. broadcast(s, name);

}

ChatServer. remove(toClient);

toClient. close();

} catch (Exception e) {

System. out. println("Chatter error: "+e);

}

}

}

class List {

// Класс Список, J M Bishop Октябрь 1997

// Поддерживает список объектов

// в порядке LIFO (Last-in-First-out),

// содержит метод-итератор.

private Node start, now, prev;

public List() {

now = null;

start = null;

prev = null;

}

public void add(Object x) {

if (start == null) {

start = new Node(x, null);

now = start;

} else {

Node T = new Node(x, now. link);

now. link = T;

prev = now;

now = T;

}

}

public void remove() {

if (isempty() || eol()) {

return;

} else {

if (prev == null) {

start = now. link;

} else {

prev. link = now. link;

now = now. link;

}

}

}

public boolean isempty() {

return start == null;

}

public Object current() {

return now. data;

}

public void reset() {

now = start;

prev = null;

}

public boolean eol() {

return now == null;

}

public void succ() {

now = now. link;

if (prev == null)

prev = start;

else

prev = prev. link;

}

class Node {

// Класс Node для хранения объектов,

// которые связаны в список.

Node link;

Object data;

Node(Object d, Node n) {

link = n;

data = d;

}

}

}

Пример 4. HTML-форма, передающая параметры сервлету. Данная форма предназначена для ввода и отсылки данных при оформлении заказа в электронном магазине.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD><TITLE>Оформление заказа</TITLE></HEAD>

<BODY BGCOLOR="#FDF5E6">

<H1 ALIGN="CENTER">Оформление заказа</H1>

<FORM ACTION="/servlet/ShowParameters" METHOD="POST">

Код товара: <INPUT TYPE="TEXT" NAME="itemNum"><BR>

Количество: <INPUT TYPE="TEXT" NAME="quantity"><BR>

Цена за штуку: <INPUT TYPE="TEXT" NAME="price" VALUE="

public class GenDemo extends Applet

{

Gen<Integer> iOb;

Gen<String> strOb;

public void init()

{

int i=Integer. parseInt(getParameter("intParam"));

iOb=new Gen<Integer>(i);

String s=getParameter("strParam");

strOb=new Gen<String>(s);

}

public void paint(Graphics g)

{

iOb. showType(g, 10,10);

strOb. showType(g, 30,10);

}

class Gen<T>

{

// объявление настраиваемого класса Gen

...

}

}

Итак, в апплет передается два параметра. Один из них – целое число, другой – символьная строка. Для хранения этих данных в классе GenDemo объявляются ссылки на объекты типов Gen<Integer> и Gen<String>. Типы данных Integer и String в данном случае являются параметрами настраиваемых типов. При создании первой ссылки параметру T класса Gen присваивается значение Integer. Это значит, что генерируется реализация класса Gen для работы с целыми числами и iOb является объектом именно этого класса. Во втором случае аналогичная работа проводится со значением типа String и объектом strOb. Далее при работе с объектом iOb везде, где упоминался тип Т в классе Gen используется тип Integer, а при работе с объектом strOb тип Т становится типом String.

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

НЕ нашли? Не то? Что вы ищете?

Приложение 4. Работа с JDK в режиме командной строки

Бывают ситуации, когда с пакетом JDK приходится работать непосредственно из командной строки, минуя какие-либо графические оболочки. Для этого операционную систему необходимо предварительно настроить. Эта настройка производится один раз. Рассмотрим правила настройки для самой распространенной в настоящее время операционной системы – Windows XP.

Операционная система должна иметь информацию, какой каталог JDK содержит программы, нужные для компиляции и запуска апплетов и приложений. Поэтому следует настроить переменную среды Path. Для этого выполните следующие действия.

·  Выберите "Пуск""Панель управления""Администрирование""Управление компьютером" и в левой части окна щелкните правой кнопкой мыши по строке "Управление компьютером".

·  В появившемся контекстном меню выберите пункт "Свойства", затем в окне свойств перейдите на закладку "Дополнительно".

·  В группе "Переменные среды" нажмите на кнопку "Параметры".

·  В списке "Системные переменные" выберите переменную Path и нажмите на кнопку "Изменить".

·  В текстовом поле "Значение переменной" добавьте точку с запятой и полное имя каталога BIN пакета JDK. Например, если JDK установлен в каталог D:\jdk1.4, то это имя будет выглядеть как D:\jdk1.4\bin. Соответственно, если переменной Path в списке не было, тогда ее требуется создать, и в этом случае точку с запятой в значении переменной указывать не надо.

Теперь можно работать с командной строкой. Выберите "Пуск""Выполнить", наберите и выполните команду cmd. Появится черное окно командной строки – окно DOS, в котором указывается строка приглашения в виде имени текущего каталога. В этом окне можно выполнять команды только в текстовом режиме. Для вывода списка стандартных команд наберите help и нажмите Enter. Чаще всего приходится использовать команды перемещения по каталогам, например:

d: – переход к диску D;

cd .. – переход к родительскому каталогу;

cd MyJava – переход к подкаталогу MyJava текущего каталога (относительная ссылка);

cd d:\MyJava – переход к подкаталогу MyJava диска D (абсолютная ссылка).

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

Теперь перейдем к работе с JDK. Предположим, мы хотим откомпилировать какой-то апплет. Сначала следует перейти в каталог, в котором находится java-файл этого апплета. Для компиляции используется программа javac:

javac FirstApplet. java

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

Теперь мы хотим просмотреть результат работы апплета. Для этого служит команда appletviewer.

appletviewer FirstApplet. html

Обратите внимание, что в качестве параметра в этой команде указывается html-файл. После выполнения этой команды будет выведено отдельное окно с запущенным апплетом (Kawa использует то же самое окно для запуска апплетов).

Для компиляции приложений используется та же команда javac, что и для апплетов, например,

javac ChatServer. java

А запуск приложений выглядит несколько по-другому. Для этого служит команда java. Например:

java ChatServer

Регистр символов в названии класса является существенным! Запустите эту команду на выполнение. Вы получите сообщение:

Exception in thread "main"

java. lang. NoClassDefFoundError: ChatServer

Данное сообщение означает, что java-машина не находит файл ChatServer.class, хотя он и находится в текущем каталоге. Для исправления этой ошибки следует вернуться к настройке переменных среды и создать переменную Classpath. Эта переменная указывает, где java-машина должна искать нестандартные классы. В качестве значения переменной укажите символ "." – это соответствует текущему каталогу.

Таким же образом подключаются и другие нестандартные классы, например, пакет для работы с mysql. Пусть он называется mysql-connector-java-3.0.8-stable-bin. jar и находится в каталоге C:\mysql. Для использования этого пакета в значение переменной Classpath через точку с запятой добавьте строку C:\mysql\mysql-connector-java-3.0.8-stable-bin. jar.

Обратите внимание, что при работе с окном командной строки русские символы выводятся в кодировке DOS, поэтому, например, кодировка Win1251 в этом окне будет нечитаемой.

Приложение 5. Коды примеров

Пример 1. Приложение, использующее потоки.

class WalkmanHire {

/* Прокат плееров-экскурсоводов J M Bishop Январь 1997

* Программа имитирует прокат плееров для посетителей музея.

* Имеется некоторое фиксированное количество плееров и не-

* сколько служащих, которые их выдают посетителям под денежный

* залог и принимают обратно с возвратом залога.

* По умолчанию имеется 50 плееров и 3 сотрудника. Эти значения

* можно изменить, если запустить программу с параметрами, на-

* пример,

* java WalkmanHire 100 8.

* Изначально сумма полученного залога равна 0.

* Иллюстрируют применение синхронизации, а также

* использование методов wait и notify.

* В программе одновременно используются потоки двух разных

* типов – класс мГруппа посетитителей" и класс "Сотрудник"

*/

public static void main (String [] args) {

// получение числа плееров, начало имитации

// деятельности музея

if (args. length >= 1)

pool = Integer. parseInt(args[0]);

else pool = 50;

Museum m = new Museum (pool);

// получение количества сотрудников,

// создание и запуск потоков для имитации работы сотрудников

if (args. length >= 2)

helpers = Integer. parseInt(args[1]);

else helpers = 3;

for (int i=0; i<helpers; i++)

new Counter (m, i).start();

}

static int pool;

static int helpers;

}

import java. io.*;

class Museum {

Museum (int w) {

walkmen = w;

cash = 0;

}

synchronized void hire (int c, int n) {

// Если недостаточно свободных плееров,

// ждать, пока не будет произведен возврат количества,

// необходимого для текущей группы посетителей

System. out. println("Сотруднику "+c+" требуется "+n+

" плееров");

while (walkmen < n) {

try { wait(); }

catch (InterruptedException e) {}

}

// Выдать плееры и принять залог.

// Пробудить следующий поток, находящийся в состоянии

// ожидания.

walkmen -= n;

cash += n;

System. out. println("Сотрудник "+c+" выдал "+n+" плееров");

System. out. println("Текущее состояние:"+

" Залог: "+cash+" Всего: "+(walkmen+cash)

+ " Плееры в наличии: "+walkmen);

notify ();

}

synchronized void replace (int n) {

// Принять плееры, вернуть залог и пробудить следующий

// поток, находящийся в состоянии ожидания

System. out. println("Возвращено "+n+" плееров");

walkmen +=n;

cash -= n;

notify ();

}

private static int walkmen;

private static int cash;

}

class Visitors extends Thread {

Visitors (Museum m, int w) {

museum = m;

groupSize = w;

}

public void run () {

// Группа осматривает экспозицию музея в течение случайного

// интервала времени (от 1 до 2 секунд), затем возвращает

// плееры и покидает музей.

// Поток "Группа посетителей" уничтожается.

try {sleep((int) (Math. random()*1000)+1);} catch(InterruptedException e) {}

museum. replace(groupSize);

}

Museum museum;

int groupSize;

}

class Counter extends Thread {

Counter (Museum m, int q) {

museum = m;

queue = q;

}

public void run () {

// Генерируется количество посетителей в новой группе,

// выдается нужное количество плееров,

// создается и запускается объект-поток

// для группы посетителей.

while (true) {

int w = a(7);

museum. hire(queue, w);

new Visitors (museum, w).start();

// Генерируется пауза перед приходом

// следующей группы посетителей

try {sleep(a(100));} catch(InterruptedException e) {}

}

}

Museum museum;

int queue;

static int a (int x) {

return (int) (Math. random() * x) +1;

}

}

Пример 2. Два потока, соединенные каналом ввода-вывода. Один поток рисует фейерверк, другой формирует для него цвет

/* Апплет, иллюстрирующий обмен данными с помощью каналов ввода-

* вывода. Апплет производит рисование залпов фейерверка.

* Рисованием фейерверка занимается объект-поток типа

* ZalpThr. Другой поток (типа ColorThr) случайным образом

* генерирует цвет очередной серии залпов.

* Для передачи сгенерированного цвета в объект-поток рисования

* фейерверка используются канальные потоки ввода-вывода,

* которые создаются в объекте-апплете.

*/

import java. awt.*;

import java. applet.*;

import java. io.*;

// класс рисования фейерверка

public class Zalp extends Applet

{

// канальный поток ввода (для чтения сгенерированного цвета)

PipedInputStream in=null;

// канальный поток вывода (для передачи сгенерированного цвета)

PipedOutputStream out=null;

public void init()

{

// создание канальных потоков ввода-вывода

try

{

in = new PipedInputStream();

// поток вывода создается на основе потока ввода

// для организации коммуникационного канала

// между ними

out = new PipedOutputStream(in);

}

catch(IOException ex)

{

}

setBackground(Color. black);

// создание потока рисования фейерверка,

// в качестве параметров конструктора передаются

// поток ввода для получения цвета рисования и

// графический контекст апплета

new ZalpThr(in, getGraphics()).start();

// создание потока генерации цвета фейерверка,

// в качестве параметров конструктора передается

// поток вывода для передачи цвета

new ColorThr(out).start();

}

}

import java. io.*;

// поток генерации цвета фейерверка

class ColorThr extends Thread

{

PipedOutputStream out;

ColorThr(PipedOutputStream out)

{

this. out=out;

}

public void run()

{

while (true)

{

try

{

// генерация компонентов цвета и отправка

// их через канал вывода потоку рисования

// фейерверка

out. write(100+(int)(Math. random()*155));

out. write(100+(int)(Math. random()*155));

out. write(100+(int)(Math. random()*155));

}

catch(IOException ex)

{

}

try

{

// задается пауза до генерации

// следующего цвета

sleep((int)(Math. random()*10000));

}

catch(InterruptedException e)

{ }

}

}

}

import java. awt.*;

import java. io.*;

// класс рисования фейерверка

class ZalpThr extends Thread

{

int M=300,N=300;

int zx, zy;

int zd;

boolean znew=true;

int r, g,b;

PipedInputStream in=null;

Graphics gr;

ZalpThr(PipedInputStream in, Graphics gr)

{

this. in=in;

this. gr=gr;

}

public void run()

{

while (true)

{

if (znew)

{

zx=(int)(Math. random()*M);

zy=(int)(Math. random()*N);

zd=0;

znew=false;

// проверяем наличие данных в потоке ввода

// если они там есть, то считываем их

try

{

if (in. available()>0)

r=in. read();

if (in. available()>0)

g=in. read();

if (in. available()>0)

b=in. read();

}

catch(IOException ex)

{

System. out. println("Exception!!!");

}

}

else

{

zd+=10;

if(zd>=M)

znew=true;

}

paint();

try

{

sleep(50);

}

catch(InterruptedException e)

{

}

}

}

public void paint()

{

int x, y;

int d;

Color col=new Color(r, g,b);

gr. setColor(col);

gr. clearRect(0,0,M, N);

if (zd==0)

{

gr. fillOval(zx, zy,10,10);

}

else if (zd<=M/2)

{

double dvaPI=2*Math. PI;

double step=dvaPI/100;

for (double i=0; i<dvaPI; i+=step)

{

d=zd/2+(int)(Math. random()*zd/2);

x=zx+(int)(d*Math. cos(i));

y=zy-(int)(d*Math. sin(i));

gr. fillOval(x, y,5,5);

}

}

}

}

Пример 3. Чат-сервер

/* Чат-сервер J M Bishop Январь 1997

* Модифицированная версия - Java 1.1 Январь 1998

* Создает сервер для обмена сообщениями.

*

* Подключение клиента:

* telnet x y

* где x и y - имя и порт компьютера,

* на котором запущен сервер.

*

* Иллюстрирует сокеты, ввод-вывод на сокетах

* потоки, синхронизацию и использование списков.

*/

import java. io.*;

import .*;

public class ChatServer {

private static List clientList = new List();

private static int id = 0;

public static void main(String[] args) throws IOException {

// Назначаем порт и создаем сокет.

int port = 8190;

if (args. length > 0)

port = Integer. parseInt(args[0]);

ServerSocket listener = new ServerSocket(port);

System. out. println("The Chat Server is running " +

" on port "+port);

// Ожидаем (слушаем) новых клиентов.

// Для каждого клиента создаем поток-обработчик.

// Добавляем клиента в связный список.

while (true) {

Socket client = listener. accept();

new ChatHandler(client).start();

System. out. println("New client no."+id+

" from "+ client. getInetAddress()+

" on client's port "+client. getPort());

clientList. reset();

clientList. add(client);

id++;

}

}

static synchronized void broadcast

(String message, String name)

throws IOException {

// Посылаем сообщение всем клиентам.

Socket s;

PrintWriter p;

for (clientList. reset();

!clientList. eol(); clientList. succ())

{

s = (Socket)clientList. current();

p = new PrintWriter(s. getOutputStream(), true);

p. println(name+": "+message);

}

}

static synchronized void remove(Socket s) {

// Ищем клиента в списке (по ссылке на его сокет)

// и удаляем его из списка.

Socket t;

for (clientList. reset();

!clientList. eol(); clientList. succ())

{

t = (Socket)clientList. current();

if (t. equals(s))

break;

}

clientList. remove();

id--;

}

}

class ChatHandler extends Thread {

// Класс ChatHandler вызывается из ChatServer:

// один поток для каждого клиента, подключившегося к чату.

private BufferedReader in;

private PrintWriter out;

private Socket toClient;

private String name;

ChatHandler(Socket s) {

toClient = s;

}

public void run() {

try {

// Создаем потоки ввода-вывода для сокета

// и печатаем приглашение.

in = new BufferedReader(new InputStreamReader(

toClient. getInputStream()));

out = new PrintWriter(toClient. getOutputStream(),

true);

out. println("*** Welcome to the Chatter ***");

out. println("Type BYE to end");

out. println("What is your name? ");

out. flush();

String name = in. readLine();

ChatServer. broadcast(name+

" has joined the discussion.", "Chatter");

// Читаем строки сообщения

// и отправляем сообщение всем клиентам.

while (true) {

String s = in. readLine().trim();

// Проверяем первые три символа для BYE.

// Избегаем проблем с разными символами конца строки.

if (s. length() > 2 && s. charAt(0) == 'B' &&

s. charAt(1) == 'Y' && s. charAt(2) == 'E') {

ChatServer. broadcast(name+

" has left the discussion.","Chatter");

break;

}

ChatServer. broadcast(s, name);

}

ChatServer. remove(toClient);

toClient. close();

} catch (Exception e) {

System. out. println("Chatter error: "+e);

}

}

}

class List {

// Класс Список, J M Bishop Октябрь 1997

// Поддерживает список объектов

// в порядке LIFO (Last-in-First-out),

// содержит метод-итератор.

private Node start, now, prev;

public List() {

now = null;

start = null;

prev = null;

}

public void add(Object x) {

if (start == null) {

start = new Node(x, null);

now = start;

} else {

Node T = new Node(x, now. link);

now. link = T;

prev = now;

now = T;

}

}

public void remove() {

if (isempty() || eol()) {

return;

} else {

if (prev == null) {

start = now. link;

} else {

prev. link = now. link;

now = now. link;

}

}

}

public boolean isempty() {

return start == null;

}

public Object current() {

return now. data;

}

public void reset() {

now = start;

prev = null;

}

public boolean eol() {

return now == null;

}

public void succ() {

now = now. link;

if (prev == null)

prev = start;

else

prev = prev. link;

}

class Node {

// Класс Node для хранения объектов,

// которые связаны в список.

Node link;

Object data;

Node(Object d, Node n) {

link = n;

data = d;

}

}

}

Пример 4. HTML-форма, передающая параметры сервлету. Данная форма предназначена для ввода и отсылки данных при оформлении заказа в электронном магазине.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD><TITLE>Оформление заказа</TITLE></HEAD>

<BODY BGCOLOR="#FDF5E6">

<H1 ALIGN="CENTER">Оформление заказа</H1>

<FORM ACTION="/servlet/ShowParameters" METHOD="POST">

Код товара: <INPUT TYPE="TEXT" NAME="itemNum"><BR>

Количество: <INPUT TYPE="TEXT" NAME="quantity"><BR>

Цена за штуку: <INPUT TYPE="TEXT" NAME="price" VALUE="$"><BR>

<HR>

Имя: <INPUT TYPE="TEXT" NAME="firstName"><BR>

Фамилия: <INPUT TYPE="TEXT" NAME="lastName"><BR>

Адрес доставки:

<TEXTAREA NAME="address" ROWS=3 COLS=40></TEXTAREA><BR>

Вид кредитной карты:<BR>

<INPUT TYPE="RADIO" NAME="cardType"

VALUE="Visa">Visa<BR>

<INPUT TYPE="RADIO" NAME="cardType" VALUE="Master Card">Master Card<BR>

<INPUT TYPE="RADIO" NAME="cardType" VALUE="Amex">American Express<BR>

<INPUT TYPE="RADIO" NAME="cardType"

VALUE="Discover">Discover<BR>

<INPUT TYPE="RADIO" NAME="cardType"

VALUE="Java SmartCard">Java SmartCard<BR>

Номер кредитной карты:

<INPUT TYPE="PASSWORD" NAME="cardNum"><BR>

Повторить номер кредитной карты:

<INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR>

<CENTER>

<INPUT TYPE="SUBMIT" VALUE="Оформить заказ">

</CENTER>

</FORM>

<br>

</BODY>

</HTML>

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

import java. io.*;

import javax. servlet.*;

import javax. servlet. http.*;

import java. util.*;

public class ShowParameters extends HttpServlet

{

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

response. setContentType("text/html");

PrintWriter out = response. getWriter();

String title = "Reading All Request Parameters";

out. println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0"+

" Transitional//EN\">\n" +

"<HTML>\n" +

"<HEAD><TITLE>List of parameters"+

"</TITLE></HEAD>\n" +

"<BODY BGCOLOR=\"#FDF5E6\">\n" +

"<H1 ALIGN=CENTER>" + title + "</H1>\n" +

"<TABLE BORDER=1 ALIGN=CENTER>\n" +

"<TR BGCOLOR=\"#FFAD00\">\n" +

"<TH>Parameter Name<TH>Parameter Value(s)");

// создаем объект-перечисление и заполняем его

// именами параметров формы

Enumeration paramNames = request. getParameterNames();

// запускаем цикл перебора элементов перечисления

while(paramNames. hasMoreElements())

{

// получаем следующий элемент перечисления

String paramName = (String)paramNames. nextElement();

out. print("<TR><TD>" + paramName + "\n<TD>");

// создаем массив строк и записываем в него

// переданные из формы значения параметра,

// имя которого хранится в переменной paramName

String[] paramValues =

request. getParameterValues(paramName);

if (paramValues. length == 1) {

// параметр имеет одно значение

String paramValue = paramValues[0];

// проверка на пустоту значения параметра

if (paramValue. length() == 0)

out. println("<I>No Value</I>");

else

out. println(paramValue);

} else {

// параметр имеет много значений (например,

// список со множественным выбором)

out. println("<UL>");

for(int i=0; i<paramValues. length; i++) {

out. println("<LI>" + paramValues[i]);

}

out. println("</UL>");

}

}

out. println("</TABLE>\n</BODY></HTML>");

}

public void doPost(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

doGet(request, response);

}

}

Литература

Основная литература, использованная при подготовке данного курса:

1.  Бишоп, Дж. Эффективная работа: Java 2 [Текст]: пер. с англ./ Джуди Бишоп. – СПб.: Питер, 2002. – 592 с.

2.  Friesen, J. Java 2 by example [Текст] / Jeff Friesen. – Que, 2000. – 848 p.

3.  Джамса, К. Изучи сам. Java сегодня [Текст]: пер. с англ. / Крис Джамса. – Мн.: ООО "Попурри", 1996. – 416 с.

4.  Холл, М. Сервлеты и Java Server Pages [Текст]: пер. с англ. / Марти Холл. – СПб.: Питер, 2001. – 496 с.

Дополнительная литература:

1.  Эккель, Б. Философия Java [Текст]: пер. с англ. / Брюс Эккель. – СПб.: Питер, 2003. – 976 с.

2.  Брогден, Б. Электронный магазин на Java и XML [Текст]: пер. с англ. / Б. Брогден, К. Мииник. – СПб.: Питер, 2002. – 400 с.

3.  Мугал, Java. Руководство по подготовка к сдаче сертификационного экзамена CX [Текст]: пер. с англ. / Мугал, Расмуссен. – М.: КУДИЦ-ОБРАЗ, 2006. – 688 с.

4.  Шилдт, Г. Java 2 v5.0 (Tiger). Новые возможности [Текст]: пер. с англ. / Герберт Шилдт. – СПб.: БХВ-Петербург, 2005. – 196 с.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7

quot;><BR>

<HR>

Имя: <INPUT TYPE="TEXT" NAME="firstName"><BR>

Фамилия: <INPUT TYPE="TEXT" NAME="lastName"><BR>

Адрес доставки:

<TEXTAREA NAME="address" ROWS=3 COLS=40></TEXTAREA><BR>

Вид кредитной карты:<BR>

<INPUT TYPE="RADIO" NAME="cardType"

VALUE="Visa">Visa<BR>

<INPUT TYPE="RADIO" NAME="cardType" VALUE="Master Card">Master Card<BR>

<INPUT TYPE="RADIO" NAME="cardType" VALUE="Amex">American Express<BR>

<INPUT TYPE="RADIO" NAME="cardType"

VALUE="Discover">Discover<BR>

<INPUT TYPE="RADIO" NAME="cardType"

VALUE="Java SmartCard">Java SmartCard<BR>

Номер кредитной карты:

<INPUT TYPE="PASSWORD" NAME="cardNum"><BR>

Повторить номер кредитной карты:

<INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR>

<CENTER>

<INPUT TYPE="SUBMIT" VALUE="Оформить заказ">

</CENTER>

</FORM>

<br>

</BODY>

</HTML>

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

import java. io.*;

import javax. servlet.*;

import javax. servlet. http.*;

import java. util.*;

public class ShowParameters extends HttpServlet

{

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

response. setContentType("text/html");

PrintWriter out = response. getWriter();

String title = "Reading All Request Parameters";

out. println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0"+

" Transitional//EN\">\n" +

"<HTML>\n" +

"<HEAD><TITLE>List of parameters"+

"</TITLE></HEAD>\n" +

"<BODY BGCOLOR=\"#FDF5E6\">\n" +

"<H1 ALIGN=CENTER>" + title + "</H1>\n" +

"<TABLE BORDER=1 ALIGN=CENTER>\n" +

"<TR BGCOLOR=\"#FFAD00\">\n" +

"<TH>Parameter Name<TH>Parameter Value(s)");

// создаем объект-перечисление и заполняем его

// именами параметров формы

Enumeration paramNames = request. getParameterNames();

// запускаем цикл перебора элементов перечисления

while(paramNames. hasMoreElements())

{

// получаем следующий элемент перечисления

String paramName = (String)paramNames. nextElement();

out. print("<TR><TD>" + paramName + "\n<TD>");

// создаем массив строк и записываем в него

// переданные из формы значения параметра,

// имя которого хранится в переменной paramName

String[] paramValues =

request. getParameterValues(paramName);

if (paramValues. length == 1) {

// параметр имеет одно значение

String paramValue = paramValues[0];

// проверка на пустоту значения параметра

if (paramValue. length() == 0)

out. println("<I>No Value</I>");

else

out. println(paramValue);

} else {

// параметр имеет много значений (например,

// список со множественным выбором)

out. println("<UL>");

for(int i=0; i<paramValues. length; i++) {

out. println("<LI>" + paramValues[i]);

}

out. println("</UL>");

}

}

out. println("</TABLE>\n</BODY></HTML>");

}

public void doPost(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

doGet(request, response);

}

}

Литература

Основная литература, использованная при подготовке данного курса:

1.  Бишоп, Дж. Эффективная работа: Java 2 [Текст]: пер. с англ./ Джуди Бишоп. – СПб.: Питер, 2002. – 592 с.

2.  Friesen, J. Java 2 by example [Текст] / Jeff Friesen. – Que, 2000. – 848 p.

3.  Джамса, К. Изучи сам. Java сегодня [Текст]: пер. с англ. / Крис Джамса. – Мн.: ООО "Попурри", 1996. – 416 с.

4.  Холл, М. Сервлеты и Java Server Pages [Текст]: пер. с англ. / Марти Холл. – СПб.: Питер, 2001. – 496 с.

Дополнительная литература:

1.  Эккель, Б. Философия Java [Текст]: пер. с англ. / Брюс Эккель. – СПб.: Питер, 2003. – 976 с.

2.  Брогден, Б. Электронный магазин на Java и XML [Текст]: пер. с англ. / Б. Брогден, К. Мииник. – СПб.: Питер, 2002. – 400 с.

3.  Мугал, Java. Руководство по подготовка к сдаче сертификационного экзамена CX [Текст]: пер. с англ. / Мугал, Расмуссен. – М.: КУДИЦ-ОБРАЗ, 2006. – 688 с.

4.  Шилдт, Г. Java 2 v5.0 (Tiger). Новые возможности [Текст]: пер. с англ. / Герберт Шилдт. – СПб.: БХВ-Петербург, 2005. – 196 с.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7