Copyright © 2018 iWay Technology Company Boulder, Colorado USA jt@iwaytechnology.com |
... built to travel the information superhighway.tm | A
limited right to copy this page for individual (non-commercial) educational use only is hereby granted. |
Presenter: John Thompson
Java's innate features (e.g., networking, multithreading) facilitate inter-app communication. We'll use these features to illustrate an Orderly Shutdown pattern for server-app control. Then we'll extend the strategies employed to show how you can implement other simple inter-app communication. (Note: This Intro session will not address RMI, JMS, or other advanced Java technologies.)
I. Networking Basics
II. Java Language Networking Features
III. Inter-App Communication Example
IV. Multi-Threading Basics
V. Java Language Threading Features
VI. Multithreaded Inter-App Communication Example -
The Orderly Shutdown Pattern
A. Background
Java is centered on the TCP/IP Networking Model (vs. the OSI, Open Systems Interconnection, Reference Model). The IP portion (Internet Protocol) defines how packets are constructed, and defines a machine addressing scheme. The TCP portion (Transmission Control Protocol) adds elements to allow reliable delivery, data integrity, and packet ordering.
By contrast, UDP/IP (User Datagram Protocol), another IP protocol, is an unreliable protocol, though still highly useful in selected applications where some lose of data may be inconsequential (audio, video, etc.).
Each computer on the Internet (or private network) must have a unique address. In IP, machine addresses are represented by four-byte values IP Addresses.
Example: 199.132.9.90.
Within a machine, there are 64K Ports available. Multiple ports on a single machine allow different applications, such as email (port 25), http(80), ftp(21), ping(7), to communicate independently with the outside word.
B. Client/Server Basics
Once upon a time, client meant desktop, and server meant data-center machine. With n-tiered architectures prevalent, whos a client and whos a server has become muddled. (Peer-to-peer is an alternative to client/server, and not considered here.)
Definition: Clients initiate connections; Servers listen for and respond to connection requests.
Detail: Servers listen on a documented port; clients connect to that port initially. The server then typically switches the conversation over to a different available and undocumented port, freeing the documented port for further connections.
Example client/server conversation: Apache web server talks to Netscape Navigator browser.
A. Sockets and ServerSockets
A Server App constructs a ServerSocket and sets it in a listening mode awaiting client connections. Once a connection is made, the ServerSocket returns another client socket to the server app code to manage the server side of this conversation.
// Server code
java.net.ServerSocket server = new java.net.serversocket( 1789 );
java.net.Socket client = server.accept(); // normally blocks
B. Addresses
Server sockets, by definition, run locally and thus are not constructed with an IP address. But, they do require a designated port (Unix - above 1024 for non-root processes).
Client sockets require an IP address and port to connect to (this couplet defines the socket, uniquely, on a network). Connecting to a server on the same machine allows use of the special IP address localhost, but the port is still required.
// Client code localhost
java.net.Socket client = new java.net.Socket( localhost, 1789 );
C. Streams
Following the Unix model, socket I/O is similar to other Java I/O. Client sockets use InputStream and OutputStream objects for communication. The flush() method is important in network I/O.
// Client code
OutputStream out = client.getOutputStream();
out.write( . . . );
out.flush(); // flush
A. The Server Code
A server listens for connections and responds when contacted.
// Create a server socket to listen for connections
java.net.ServerSocket server = new ServerSocket( PORT );
// accept() blocks til client request, then creates new
// socket on which to conduct client conversation.
java.net.Socket client = server.accept();
java.io.InputStream in = client.getInputStream();
byte[] inputStringBytes = new byte[ 256 ]; // Big enough?
int inputLen = in.read( inputStringBytes );
System.out.println( "\nServer received: " +
new String( inputStringBytes, 0, inputLen ) );
B. The Client Code
A client must know the IP address and port of the service app.
// Connect to server on same machine, documented port
java.net.Socket client = new Socket( "localhost", PORT );
java.io.InputStream in = client.getInputStream();
java.io.OutputStream out = client.getOutputStream();
out.write( new String( "Hello, Server." ).getBytes() );
out.flush();
C. Server Output - Server received: Hello, Server
D. Example: run portcomm
A. Background
Multithreaded code allows concurrency of execution without the heavy weight of multiple processes. Multiple threads are either swapped on and off the cpu, or may run concurrently on multiple-cpu boxes.
All threads in an app can share the same basic process resources file handles, heap memory space, the resources of the JVM. Each thread has its own program counter and its own stack memory for local data (non-static).
Since threads share much of the environment, synchronization of access to various resources and code segments is necessary. Synchronization can be thought of as single-file access one at a time.
Another key thread synchronization concept is thread shutdown. Controlling threads should normally join (wait for termination) with threads theyve stopped, to insure proper thread completion.
B. Classic Concurrency Problem
The statement k++ is not thread-safe (depending on k). Consider the machine-language implementation
Now, consider two threads, each accessing k. There is a timing issue.
A. Threads and Runnables
There are two related ways to create threads in Java. One is to extend the class java.lang.Thread
.
The other is to implement interface java.lang.Runnable
in your class and give
an instance to a Java Thread.
Either way, a run()
method executes once the Threads start()
method is called.
The keyword synchronized
protects blocks of code, or methods, from
being executed by more than one thread at a time.
Method join()
is another important synchronization device.
B. Threads The Conceptual and Semantic Challenge
A Java Thread object is similar to any instance instantiated and managed by the ClassLoader like any other object.
An OS Thread is an operating system construct that manages the execution of the code in
a Java Threads run()
method.
Once the OS Thread terminates, the Java Thread object remains. Its methods can be invoked, giving access to member data from its execution.
C. Example: run multithreading
A. What is a Pattern?
There are differing opinions notes from Deepak Alur, et al, Core J2EE Patterns.
"A recurring solution to a problem in a context."
Patterns
During pattern identification, we may observe differing implementation strategies, but where the solutions are similar a pattern may lurk.
Patterns vs. Strategies
B. Pattern Template
Context Server application conducting integral units of work that must not be interrupted (akin to the database concept of Atomic operation).
Problem How to shutdown the server app without interrupting app during a critical phase (within some unit of work that would be hard to recover from if disrupted).
Forces Unix offers signals, Windows-NT offers Services each a platform-dependent device to control server startup and shutdown.
Java run anywhere begs for a platform-independent approach.
Java language has necessary features and constructs to support a solution.
Solution Use Java networking and threading language features to implement a portable mechanism as a reusable design pattern.
-- Strategies Different strategies relate to the level of encapsulation of functional pieces, and the amount of multithreading in the solution. (For example, while there must be a thread blocking on a
SeverSocket.accept()
call, there may or may not be additional worker threads that must be notified that its time to quit SeverSocket.setSoTimeout()
allows other strategies.)-- Structure - Sequence diagrams
Consequences More threading increases complexity, albeit along fairly standardized lines. Worker threads allow encapsulation and scalability of function without additional design burden or code complexity.
Sample Code See running examples portmanager-basic and portmanager-full.
John Thompson is a Boulder, Colorado-based consultant with decades of experience in the business and development of software. A relative latecomer to Java, he has since produced over 125,000 lines of production server-side Java for his own and other businesses -- and now "gets it."
John does a majority of his development and builds on a Windows desktop and deploys, unaltered, on the Open Source platform of Linux, Apache, Tomcat and MySQL. Other platform work includes Solaris, Oracle, JRun, and WebLogic.
His business interests include aiding companies that face the challenge of software delivery. His technical interests include delivering specific functionality of demonstrable quality on a timeline.
For aid in deploying your web apps to a license fee-free open source platform, contact John at jt@iwaytechnology.com.
Copyright
© 2018 iWay Technology Company Boulder, Colorado USA jt@iwaytechnology.com |
... built to travel the information superhighway.tm | A
limited right to copy this page for individual (non-commercial) educational use only is hereby granted. |