�����: ������� �����,
�������� ����������� ���. ������� ��������
��������
�������:
19.05.2002
� ����������� ���� ��������� ����� � ����� (thread) � ��� �� ����������� ������������ ���������� � Java. � ���� ���� �� �� ��������� � ������������� �� ������������� ��� �������������� ������������.
��� ����� ��������, � ����� ������� ����� ������������ ������������ ������ �� ��� ������. �������� � ���� ����� ���� ������������ ����� ������� �� ������� �� ������ ���� �� ���� � ���� ������. �� ����������, �� �������� �� ������ �� ����� Account, � ���������� ����� ��� �� ��������� �� ����� Bank:
public class Account {
�� private double
mAmmount = 0;
�� void
setAmmount(double aAmmount) {
������ mAmmount =
aAmmount;
�� }
�� double getAmmount() {
������ return mAmmount;
�� }
}
public class Bank {
�� public static void
deposit(
������ Account aAcc,
double aSum)
�� {
������ double oldAmmount
= aAcc.getAmmount();
������ double newAmmount
= oldAmmount + aSum;
������ aAcc.setAmmount(newAmmount);
�� }
}
���� ������� ������� �� ������
������������ �� ������ ��������� 100 � 500 ���� � �������� acc, ����� � ������. ���� �� ����� ��
����� �� ������� �����:
������ 1: Bank.deposit(acc, 100);
������ 2: Bank.deposit(acc, 500);
����� �� ����� �� ����, ����������� �� ������� �� ���� ��� ������ ������ ����: ������� ������ �� ��������. ������ ������ �� ������� ��� ���. ��������� ������ ���� � ��������. ��� �������� �� ������� �� ���� �� ������� ������� �� ���������� ������������, �� �� ������ �������� ��������� �����: ������ 1 ������� ������ �� �������� � 0 ����. ������ 2 ������� ������ �� �������� � ���� 0 ����. ������ 1 ������� ��� ����������� ���� 100 ���� � ������� � �������� ������ ���� � 100 ����. ������ 2 ������� ��� ����������� ���� 500 ���� � ������� � �������� ������ ���� � 500 ����. � �������� � �������� �� ��������� 500 ������ 600 ����, � ���� �� ���� ����� ���� � ��������� �����������. ���������� �� �� ���������� ���������������� �������.
������ ������� ���������� ����� ��� ������� ������� �������� �� ������� ������������ �� ���������� ������ �� ��� ������, �� ��������� ��������� ������ ������� �� ���� � �������. ������ ������ �������� ����������������� ��������, � ��������� �� ���������� �� �������� �������������.
��������������� ������ ���������� � ������������ ������ �� ���� �������, ���� ����� ������� �� ��� ��������������. �� ����������� ���������� �� �������� � ���������������� �� ����� �����, ���� �� ������ ���� ������ �� ���������, ������ �������� � ����� � �� ���������� ���� ���� ���� �� ��������. ���� ������ ������ �� � ����������� � �� ������ �� ����������� ���� ���������� �� �������������, ����� �� ���� ������������� ������� ��� �����������, �� ����� ������������ �������.
� Java ����������
�� ������������� �� ��������. ���������� ���� synchronized ����������� �������������� ���������� ��
��������� ����. ���� ��������, �� ��� ����� �� ����� ������������ �� ����������
��������� ��� ���� ����. ��� ������ � ��������� ���������� �� ��� �� �����,
������� �� � ������ �� �������. ��������� � ������� ����� �� ����� �����
������, ���� ������� ������������ �� ������ deposit()
�� ������� ��������
public static void deposit(
�� Account aAccount, double aSum)
� ������������
synchronized public static void deposit(
�� Account aAccount, double aSum).
���������� ���� synchronized, �������� ��� ������������
�� ����� ����������� �������������� �� ������������ �� ���� ����� �� ������, ��
����� ��� ����������, � ��� �������� ������ � �� �����, �� ����� ���
����������. ��������������� �� ��������� ��� �� ������� ����� �����������
���������� �� ���� ����� ��� ��������� �� ������������ �� ��������������� ��� �
���������� ��� ���������� �� ������������ ��. ������ ����� ����� �� ����� ��
������� ������������� ���, ����� ����� � ��������, �� ������������ �������
������������ �� ���� �����. ���� ���, ������������� �� ���� � ��� �����, ��
���� �� �� ��������� �� ��� ����� ������������ � �������� �� ������������ �� ��
���������� ���� ���� �����. � Java ��������������� ���� �� ����� �� �����
�����, ������ � �������� � �������� �� ������ ������� �������� ����� ���� java.lang.Object. � ������ ������ ����
��������� ���� synchronized
��������������� ������� �� ������ deposit()
�� �������, ����� ��������, �� ����� ������� �� ����� �� ����� ������������
���������� �� ���. �������, �� ���� ������ ��������, ����� ������ �� �
��������, ������ �������� ������ �����, ������ ���� ��������, � ����� ��
������. �� �� ���������� ���� ��������,� �� ����� ������� deposit() ����������� ������ ����� ��
���������� ������� ������������� ���:
public static void deposit(
�� Account aAccount,
double aSum)
{
�� synchronized
(aAccount) {
������ double oldAmmount
= aAccount.getAmmount();
������ double newAmmount
= oldAmmount + aSum;
������ aAccount.setAmmount(newAmmount);
�� }
}
���� ���� ������ �������� ��������, ������ �������� ���� ��������, ����� �� �������, � �� ������ �����. ����� � ������ �� �������� ���������� �� ������, �� �� �������� ���� ���� �����, ����� �� ������� � �� ���� �� �������, ���� ����� �� �������, � �� �� ��-�����, �� �� ���� ������������� ����� �� ����� ��������� ��� ���� �� ������ �� ����. ����� ����, ��� �������� �� ������� ����� ������ �� � �������������, ��� ������ �� � ������������� ���������, ������ �� ������ � ���� �����. � �������� ������ ����� �� ��������������� ����. �������� ��� � ������ ����� ��������� �� ���� � ��������������, � ��������� �� � ��������������, ������������ �� ������ ��� ����������� �������� �� �� ������ ������ ������.
������� ��
��������������� ���� ���������� ���� synchronized
����� ������ � �������� ������, �� ������ �� � ����������. �� ���� � ����� java.lang.Object ����������� ��� �������
����� ������ �������� ��� ��������������� � wait(),
notify() � notifyAll(). ������� wait() �������� �������� ����� �� �����
����� ������ ����� ����� �� ������ notify()
�� ����� ����� �� �� � ������. ������� notify()
������� ���� �� ��������� �� ����� ����� �����, � notifyAll() ������� ��������. ��� �� ������ ���� �������
�����, notify() � notifyAll() �� ������ ����. �������� �� �������� �� ���� ����� � ��������� ������,
����� �� �������� � �������� �� �������� �� ����� �����. � ���� ������ �������
����� ������ �� ������ ������� �� ������ ������� ������ � ���� ���� �� ��������
������ ����������. ��� ������� ����� � ���� ����� ��������� ��������� ����
������� � �������� ���������� ������, �� �� ��������� �� ��������� ����� �����
���������� ����� � �� ������ ������������������ �� ������ �������. �����
��-��������� � ������� ����� �� �����, ��������� ��������� �� �������, �
������� �� ������ ���������� ������ � ������� ���� ���� �� ������ �������.
������������ �� ��������� (��� ����� ��� �� ������� ���������) ����� �, �� ��
���������� ���������� �����, ����� � ��������� ������������ �� ����� �� ����
����������� ����� �� ������ �� �������.
�� ���������� ���� ���������� �������, �������� ���� ������������� � ����������. ���� ����� ���������� ������� ��������� � ��������� ��� �������� � ����� ���� �� ������ ������� ���������� ���������� �� ���. ������ ���������� �� �������� ������� ����� ������ ������ �� ������� ���� �� ����������� �� �� �������� �����. ���������� �� ����� �� ����� ����� � ���������� � ������� ���� �� ������������� ���������. ������ �������� ����� � ������� � ������, ��� ���� ������ ������� ��������� ���������, �� �� �� � �������. ���������������� ����� ������������� (������) � ������������� (����������) ������������ ��������� ������, � ����� ����� ����� ������ ������, �� ������������ ������ �� ������� � �� ������� ��� � ����������. ��������� ������������� � ���������� �� �������� � ���� �� �� ���������� �������� �������������� ������ �� �������������� ����� ������������� � ������������� ��� �� �� ������ ������� ���������� ����� ������ ����� ���� ������ �� ������� ������. ���� ���������, ����� �������������� ���������� � ������������� ���������� �� �������� ���������, � �������, � ����� �������������� ���������, � ������ � ���������� 5 ���������. �������� � �������� � �������� ������� �� ��������, ����������� �� ������ �� ���������� �� ������������� � Java:
import java.util.*;
class Producer extends Thread {
static final int MAXQUEUE = 5;
private Vector messages = new Vector();
�
public void run() {
try {
while (true) {
putMessage();
sleep(1000);
}
} catch(InterruptedException e) { }
}
�
private synchronized void putMessage()
throws InterruptedException
{
while (messages.size() == MAXQUEUE)
wait();
messages.addElement(
new Date().toString() );
notify();
}
�
// Called by Consumer
public synchronized String getMessage()
throws InterruptedException
{
notify();
while (messages.size() == 0)
wait();
String message =
(String)messages.firstElement();
messages.removeElement( message );
return message;
}
}
�
class Consumer extends Thread {
Producer producer;
����
Consumer(Producer p) {
producer = p;
}
�
public void run() {
try {
while (true) {
String message =
producer.getMessage();
System.out.println(message);
sleep(1500);
}
} catch( InterruptedException e ) { }
��� }
}
public class TestProducerConsumer {
public static void main(String args[]) {
Producer producer = new Producer();
producer.start();
Consumer c1 = new Consumer(producer);
c1.start();
Consumer c2 = new Consumer(producer);
c2.start();
}
}
������������
���� �� ���������� � �������������� �� �������� wait() �
notify(), �������� �� �� ������� �����������, ��
���� ������ ����� �� �� ����� ���� �� ���, ����� � ������������� �� ������, ��
����� �� �����������.
��� ������� ��
��������� � ������� �� ��������� �� ����� �� �������� ����� � �� � ������� ���,
�������������� �� ���� � ��� �����, �� �������� ���� ����������� �� �������
����� �����, ����� � ������� ������ �� �� �� �������, ������ �� ����
������������ �� ��������� �����. ��������, �� � ����� ����� �� ������ �� �����
�������, ���� ������ �� ���� ������� �� � ������, � ������� �� ���� ������� ��
������ �� ��������������� ���, �� ���� ���� �� �� ����� ������ ������ �
�������. ���� �����������, ����� �� ��������, ������ ����������� �� wait() ��
���� �������� �������� �����, �� � �������� ������, �� ����� �� �
��������������. ���� ��������� �� ������ �������� notify(), ����� � ������������� �� ����� �����, �� �� �������.
����������� �� notify() ������� ��������� �����, �� �� �
��������� ������� �� �������� ������������ ��. ���������� ����� �������
������������ �� ��������������� ����, �� ����� � ������� notify(). ���� ���� ���������� ������������ �� ���� �������� ������
����������������� ����� � �� �������� ���� ���� ������������ �� ���������������
����, � ����� � ���� �������. ���� ����������� �� ����� �������, �������� ��� deadlock ��� ������ ������ �� ��������. ���
���������� �������� �� ���������� �� �������������, �����, ������������ ��
������ ������ ������ �� � ���������. ����������� �� ����������� � ��
����������� ������������ ��� ��� ������ ����� � ����� ������ �� �������� �� ��
����� �������.
����� ���� ����� �� ������� ������� �� �������� �����������,
����� ���������� � ��������, TCP �������� �������������
�������� ���������� ����������� ����� �� ����� ����� ��� ����������.
������������, ����� �� ����������� ���� �����, ����� ��
�� ���������� �� ���� � ��� �������� ��� �� �������� ��������, �������� ��
����� �� ���� �������� ��� �����
TCP/IP �����. ���� ���������� ����� ��� ���� � ������� � �������.
��������� �� �������� ��� ��������� �� IP ����� � �����
�� ���� ���� ����� java.net.Socket. ��������� ������� ������� ���� ����� java.net.ServerSocket.
�� ���������� ��������� ���� �� ���� �� ���� ������ ��������� ���������� � DateServer:
ServerSocket srvSock = new ServerSocket(2002);
while (true) {
Socket socket = srvSock.accept();
�� OutputStreamWriter
out =
������ new
OutputStreamWriter(
socket.getOutputStream() );
�� out.write(new Date()+
"\n");
�� out.close();
�� socket.close();
}
���� ������ ������ �� ������� TCP ���� 2002, ���� ����� � ��������
����� ������ �������, ������� �� �������� ���� � ��� � ������� ���� ����
������� ������ � ���. ���������� �� ����� �� ������� ����� ���� �� �������
����� �� ����� ServerSocket, � ������������ �� ����� �� ������ ������ �� �����.
���������� �� ������ �� �������� �� ������ accept()
�� ����� ServerSocket, ��� ����������� �� ����� �������� ����� ������� �� ������������
�� ��������� ������, ���� ����� ������� ����� ����� �������
� ������������ ������. �� ���������� ����� �������� ����� �������� ����� ��
��������� �� ����� ��� ������� (���� ������ getOutputStream())
� ������� � ���� �������� ���� � ���, �������� �� ���� �������� �����.
����������� �� �������� ����� � �����. �� ����������� �������������� ���������
�� ������� ��� �������, ������ ������� ������ flush() �� �������� �����. ��� ���� ���� �� �������� close() ��� flush() �� ���� �������, �������� ���� �� ������ ����,
������ ����������� ����� �� ������� � ������ �� ������ �
���� �� ��������� �� ����. ������, ����������� �� ������ ����������� ����������
�� ������������� � �������. ������� ����� �� ���������� ��� ������������
��������� telnet, ����� � �������� � �������� ������ ��
Windows, Linux � Unix ����
������� �� ��������� �������� �������:
��� telnet
localhost 2002
���������� � ���������� �� ������� ����:
Sat
May 18 22:46:55 EEST 2002
���� ���� ������� ������ �� ����� ������ � ��������, ����� �� ������� ��� ����, ����� ������ � ����, ����� ��� ����� � �� ��������� �� ���������. ��������� ���� �� ���� � ��������:
Socket socket = new Socket("localhost",
2002);
BufferedReader in = new BufferedReader(
�� new
InputStreamReader(
������ socket.getInputStream() ) );
System.out.println(in.readLine());
socket.close();
����������� ��� ������ ����� ����
����������� �� ����� �� ����� java.net.Socket, ���� � ������������ �� �� ������� IP
������ ��� ����� �� ������� � ������ �� �����.
�� ��������� ������� ����� �� ����� ������� ����� � �� ������� ����, �����
�������� �������. ���� ����������� �� ������ ������� �� �������. ��� ������ ���
������ � ������-������� ������ �������� ��������� ������, � �������� �� �����
�� ������� ���������� (exceptions).
������ � ������������ � � ����� ��������, ����� ������� �� ������,
�����, ����� ���������� �� ����� �� ���� �������� � try ... catch ����, �� �� �����
���������� ���������� ������������ ������. ������ ��������� � ���-������������
��������. �������� ��� �������� �� � ������ � �������� �� ����� �� �� ������ �
����, ��� �������� ����� ������� � ������� �� ��������, ��� �������� �� �����
�� ����� �� ���� ���� ���� � � ����� ����� ������. ���� �� ����� �������� �, ��
��� �������� �� ����� �� ������� ����� �� �������, � ��� �� �� ������� ����, ��������
�� ������� �� ��������� �� ������. ������ �������� � �������� ������ ��
����������� �� ������������� �������� � �� ������� �������� � �� �� �������
��������.
�������� ��-���� ������ �� ������ �������� ��������� ��������������. ��� ����� ������� ������������ ����� ������, ������� �� ���� �������� �������, � ������� ���� ���� ����������� �� ������������ �� ������. ���� ��������� ������, �� ���� �� ������ �������, � ����� ������������ �� ������ ������ ����� ����� �����. � �������� ������ ������������ �� ���� ������ ������ �������� ����� � ���������� ������� �� ����� �� ����� ������ �� �� �����. ������ �� ������ �������� �� �� �������� ��������� ������������ � ���������� ���� �� ����. �� ���������� �� ���� ��������� � ������� �� Java �� �������� ������������� ������, ��� ����� �� ����� ������ �� ������� ������� �����. ���� � ������������� ����� �� ���������� �� �������, ������������� �� ������� � ������ �� ���� ������. �� ������������� ������ �� ������������� ������ � ���� ���������� ������ � ������ �� ��������� (chat server):
import java.io.*;
import java.net.*;
import java.util.Vector;
public class NakovChatServer {
��� public static void main(String[] args)
��� throws IOException {
������� ServerSocket serverSocket =
����������� new ServerSocket(5555);
������� System.out.println("Nakov Chat Server"
����������� + " started on port " +
����������� serverSocket.getLocalPort());
������� ServerMsgDispatcher dispatcher =
����������� new ServerMsgDispatcher();
������� dispatcher.start();
������� while (true) {
����������� Socket clientSock =
��������������� serverSocket.accept();
����������� ClientListener clientListener =
��������������� new ClientListener(clientSock,
������������������� dispatcher);
����������� dispatcher.addClient(clientSock);
����������� clientListener.start();
������� }
��� }
}
class ClientListener extends Thread {
��� private Socket mSocket;
��� private ServerMsgDispatcher mDispatcher;
��� private BufferedReader mIn;
��� public ClientListener(Socket aSocket,
��� ServerMsgDispatcher aServerMsgDispatcher)
��� throws IOException {
������� mSocket = aSocket;
������� mIn = new BufferedReader(
����������� new InputStreamReader(
��������������� mSocket.getInputStream()));
������� mDispatcher = aServerMsgDispatcher;
��� }
��� public void run() {
������� try {
����������� while (!isInterrupted()) {
��������������� String msg = mIn.readLine();
��������������� if (msg == null) break;
��������������� mDispatcher.dispatchMsg(
������������������� mSocket, msg);
����������� }
������� } catch (IOException ioex) { }
������� mDispatcher.deleteClient(mSocket);
��� }
}
class ServerMsgDispatcher extends Thread {
��� private Vector mClients = new Vector();
��� private Vector mMsgQueue = new Vector();
��� public synchronized void addClient(
��� Socket aClientSocket) {
������� mClients.add(aClientSocket);
��� }
��� public synchronized void deleteClient(
��� Socket aClientSock) {
������� int i = mClients.indexOf(aClientSock);
������� if (i != -1) {
����������� mClients.removeElementAt(i);
����������� try {
��������������� aClientSock.close();
����������� } catch (IOException ioe) {}
������� }
��� }
��� public synchronized void dispatchMsg(
��� Socket aSocket, String aMsg) {
������� String IP = aSocket.getInetAddress().
����������� getHostAddress();
������� String port = "" + aSocket.getPort();
������� aMsg = IP + ":" + port + " : " +
����������� aMsg + "\n\r";
������� mMsgQueue.add(aMsg);
notify();
��� }
��� private synchronized String
��� getNextMsgFromQueue()
��� throws InterruptedException {
������� while (mMsgQueue.size() == 0)
����������� wait();
������� String msg = (String) mMsgQueue.get(0);
������� mMsgQueue.removeElementAt(0);
������� return msg;
��� }
��� private synchronized void
��� sendMsgToAllClients(String aMsg) {
������� for (int i=0; i<mClients.size(); i++) {
����������� Socket socket =
��������������� (Socket) mClients.get(i);
����������� try {
��������������� OutputStream out =
������������������� socket.getOutputStream();
��������������� out.write(aMsg.getBytes());
��������������� out.flush();
����������� } catch (IOException ioe) {
��������������� deleteClient(socket);
����������� }
������� }
��� }
��� public void run() {
������� try {
����������� while (true) {
��������������� String msg =
������������������� getNextMsgFromQueue();
��������������� sendMsgToAllClients(msg);
����������� }
������� } catch (InterruptedException ie) { }
��� }
}
���� �������������� �������� �� � ������. ������������, ����� ����� ��� � �� ������ ��������� �� ��������� �� � �� ������� ����� ������ ��������� �� ����� ������, ���� ��������� � ���� �� ���� �� � �������. ����� �� �� ���������� ���� ������� ������� telnet-����� ��� ���� 5555 �� ����� �����, ����� � ������� ������ � Date-�������.
�������� ��� ��� ������� �����. ������ � �������� �������� (NakovChatServer), ����� ����� �� ����
5555 � ������ ���� �������, � ������� � �������-�������� (ServerMsgDispatcher),
����� �������� ���������� �� ��������� ��������� �� ������ �������� ���
�������. �� ����� ������ � ������� �� ������� ��� ���� ����� (����� �� ����� ClientListener), ����� ����� ��
���������� �� ��������� �� ����. ��� ������������ �� �������� ������ �� �������
���� 5555, ������� ��������� �� ��������� � �� ��������. ���� ���� � ��������
����� ������� �� ������ �������, �� �� ������ � ������� �� ���������, ��
������� �� ���� ����� �� ���������� �� ����������� �� ��� � �� � ��������.
������� �� ���������� �� ��������� �� ������ � �������� �� ����� (������ run()) ���� ��������� �� �������, ������
�� � �������� �� ��������� (���������� ������ DispatchMsg()), ���� ����� �� ������� ��� � ������ (����
�� notify() ������). ��������
�� ��������� ����� � ������ readLine()
� � ��������, ����� ������� ������� ������ �� ��������� ��������� ��� ��
������� ������. ��� ���������� �� ������, �������� ��
�������� �� ������� �� ��������� (���� ��������� �� deleteClient()).
������� ServerMsgDispatcher �
����� ������ �� ���������� �� �������� ������������� � ����������
� ����������. � �������� �� ����� (� ������ run())
������� ����� �� �������� �� ��������� ��������� � �� �������� �� ������
�������. � ���� ����� �� �� ����� ���������� �� ���������. ��� �������� �
������, ������� ���� (���������� wait())
������ ��������� ���� ���������. ����������� ��������� ����������
���� ���������� �� ������� �� ���������� �� ������. ��������� ������
������ �� ������������ �� ���������. ���������� ���� ������ ������� ������� �
���� ������. �� �� �������� ������� ��������, �������� ������ � ���� ����� ���
������ ��� ������������ �� � �� �������� �� ��� ��� ������ ��������� ���� ��
��������� ��� ���������� �� ��������� �� ����. ���� ��������, ��� ��������
������� ������, ��� �� ���� ��������� �� �������, ������ �������� �� ���������
�� ���� �� �� �������. ����� � �������� �� � �������� �� �������� ����� �������
������������, �� ���� ��� ��� �� ������, �� � ����� �������. ��������� �, ��
�������-��������, ����� ������� ���������� ���������, ������ ��������������. ��
�� ��������� ��� ����������� �� �������� ��������� �� �������� ������ ��
������� �������� �� ������ �������. ��� �������� � ���� �� ��������� � �����
�����, ������ ���� ������ �� �� ������ �� ����� ����� �� ������� ����������
��������� ���������. ��� ���� � ���������� ���������� �� ������ ���������.
������� ������� � �� �� ������� �� ���� ����� �� ����� ��������� �� ���������
�� ����� ������. ���� ����� ��������, �� ��� �������� ��� 1000 ������� � ������
����� ������������ 100 ���������, �� ������ �� ������� 100000 �����, �� ��
�������� ����������� �� ���������. ����������� � ������������ �� ������� �����
����� �����, ������� ������� ���������� ���������� ����� � ����� (������� ���
������������ �� Java), ���� �� �� �� � ��������� �����
����� �������� �� �� ���� ���� �������������� chat-������
�� ������ ��� ������������� �������. ��� ���� � ��-������� �� ����� ������ ��
�� ������� �� ���� �����, ����� ����� �� ���������� �� �����������,
������������� �� ����. ���� ����� ������ �� �������� ������ �� ���������,
������ ��� ����������� ��������� ��-����� ��������� �� ����� �� �� ��������, ��
�������� �������. �� ������ �� �������, ������ ��������� ������ � �� ��
�������, ������ � ��� ������� ���������. ���� ����� ���� �� �� ��������� ��
����� ����� ���� ����� ServerMsgDispatcher,
������ ��� ����� ������ ��������������. �������� ���������� �� ���� ������ ���
�� ����� �� ����� ��������� ������������ � Java� � http://inetjava.sourceforge.net.