e-Science e-Business e-Government and their Technologies Advanced Java - PowerPoint PPT Presentation

1 / 132
About This Presentation
Title:

e-Science e-Business e-Government and their Technologies Advanced Java

Description:

... and the application mainly to science but also to business and government ... 4)Grid Systems: GT3/Cogkit, Gateway, XSOAP, Portlet ... – PowerPoint PPT presentation

Number of Views:95
Avg rating:3.0/5.0
Slides: 133
Provided by: grid9
Category:

less

Transcript and Presenter's Notes

Title: e-Science e-Business e-Government and their Technologies Advanced Java


1
e-Science e-Business e-Government and their
TechnologiesAdvanced Java
  • Bryan Carpenter, Geoffrey Fox, Marlon Pierce
  • Pervasive Technology Laboratories
  • Indiana University Bloomington IN 47404
  • January 12 2004
  • dbcarpen_at_indiana.edu
  • gcf_at_indiana.edu
  • mpierce_at_cs.indiana.edu
  • http//www.grid2004.org/spring2004

2
What are we doing
  • This is a semester-long course on Grids (viewed
    as technologies and infrastructure) and the
    application mainly to science but also to
    business and government
  • We will assume a basic knowledge of the Java
    language and then interweave 6 topic areas
    first four cover technologies that will be used
    by students
  • 1) Advanced Java including networking, Java
    Server Pages and perhaps servlets
  • 2) XML Specification, Tools, Linkage to Java
  • 3) Web Services Basic Ideas, WSDL, Axis and
    Tomcat
  • 4)Grid Systems GT3/Cogkit, Gateway, XSOAP,
    Portlet
  • 5) Advanced Technology Discussions CORBA as
    istory, OGSA-DAI, security, Semantic Grid,
    Workflow
  • 6) Applications Bioinformatics, Particle
    Physics, Engineering, Crises, Computing-on-demand
    Grid, Earth Science

3
Course Topic 1
  • Advanced Java Programming
  • We will assume basic Java programming proficiency
  • We will cover Java client/server, three-tiered
    and network programming.
  • Ancillary but interesting Java topics to be
    covered include Apache Ant, XML-Beans, and Java
    Message Service
  • Material in the last bullet will mostly be
    introduced in later sections, as the course
    unfolds.
  • First lecture of the segment starts with a fairly
    discursive review of Java features.

4
Reading Material
  • No particular text for this section, but some
    material will come from earlier related courses
  • Java HPC Course, September 2003
  • http//www.hpjava.org/courses/arl
  • Opennet Technologies Online Course, Fall 2001
  • http//aspen.ucs.indiana.edu/ptliu
  • Applications of Information Technology I and II,
    Spring 2001
  • http//aspen.ucs.indiana.edu/it1spring01
  • http//aspen.ucs.indiana.edu/it2spring01

5
Java History
  • The Java language grabbed public attention in
    1995, with the release of the HotJava
    experimental Web browser, and the subsequent
    incorporation of Java into the Netscape browser.
  • Java had originally been developedunder the name
    of Oakas an operating environment for PDAs, a
    few years before.
  • Very suddenly, Java became one of the most
    important programming languages in the industry.
  • The trend continued. Although Web applets are
    less important today than they were originally,
    Java was rapidly adopted by many other sectors of
    the programming community.

6
The Java Virtual Machine
  • Java programs are not compiled to machine code in
    the same way as conventional programming
    language.
  • To support safe execution of compiled code on
    multiple platforms (portability, security), they
    are compiled to instructions for an abstract
    machine called the Java Virtual Machine (JVM).
  • The JVM is a specification originally published
    by Sun Microsystems.
  • JVM instructions are called Java byte codes.
    They are stored in a class file.
  • This execution model is part of the specification
    of the Java platform. There are a few compilers
    from the Java language to machine code, but it is
    hard to get these recognized as Java compliant.

7
JVM and Performance
  • The first implementations of the JVM simply
    interpreted the byte codes. These
    implementations were very slow.
  • This led to a common misconception that Java is
    an interpreted language and inherently slow.
  • Modern JVMs normally perform some form of
    compilation from byte codes to machine code on
    the fly, as the Java program is executed.

8
Run-time Compilation
  • In one form of Just-In-Time compilation, methods
    may be compiled to machine code immediately
    before they are executed for the first time.
    Then subsequent calls to the method just involve
    jumping into the machine code.
  • More sophisticated forms of adaptive compilation
    (like in the Sun Hotspot JVMs) initially run
    methods in interpreted mode, monitor program
    behavior, and only spend time compiling portions
    of the byte code where the program spends
    significant time. This allows more intelligent
    allocation of CPU time to compilation and
    optimization.
  • Modern JVMs (like the Hotspot server JVM)
    implement many of the most important kinds of
    optimization used by the static compilers of
    traditional programming languages.
  • Adaptive compilation may also allow some
    optimization approaches that are impractical for
    static compilers, because they dont have the
    run-time information.

9
Features of the Java Language
10
Prerequisites
  • We assume you know either Java or C moderately
    well.
  • But some things, like threaded and network
    programming with Java, will be covered from an
    introductory level later on.
  • In this section I will only point out some
    features and terminologies that are
    characteristic of Java and that you probably
    should understand.
  • And highlight some of the differences from C.

11
What Java Isnt
  • C, mainlynow hard to think of languages as
    closely related.
  • Similar syntax for expressions, control
    constructs, etc, but these are perhaps the least
    characteristic features of C or Java.
  • In C use features like operator overloading,
    copy constructors, templates, etc, to create
    little languages through class libraries.
  • Worry about memory management and efficient
    creation of objects.
  • Worry about inline versus virtual methods,
    pointers versus references, minimizing
    overheads.
  • In Java most of these things go away.
  • Minimal control over memory management, due to
    automatic garbage collection.
  • Highly dynamic all code is loaded dynamically
    on demand implicit run-time descriptors play an
    important role, through run-time type checks,
    instanceof, etc.
  • Logically all methods are virtual overloading
    and implementation of interfaces is ubiquitous.
  • Exceptions, rarely used in C, are used
    universally in Java.

12
Java Class Structure
  • All methods and (non-local) variables are
    explicitly member of classes (or interfaces).
  • No default, global, namespace (except for the
    names of classes and interfaces).
  • Java discards multiple inheritance at the class
    level. Inheritance relations between classes are
    strictly tree-like.
  • Every class inheritance diagram has the universal
    base class Object at its root.

13
Java Class Structure (2)
  • Java introduces the important idea of an
    interface, which is logically different from a
    class. Interfaces contain no implementation code
    for the methods they define.
  • Multiple inheritance of interfaces is allowed,
    and this is one way Java manages without it at
    the class level.
  • Since Java 1.2, classes and interfaces can be
    nested.
  • This is a big change to the language read JLS
    2nd Edition in detail if you dont believe this!

14
Classes and Instances
  • Will consistently use the following terminologies
    (which are correct)
  • A class is a type, e.g.
  • public class A int x void foo() x 23
  • An interface is a type, e.g .
  • public interface B void goo()
  • An instance is an object. An object is always an
    instance of one particular class.
  • That class may extend other classes, and
    implement multiple interfaces.

15
Pointers in Java?
  • Any expression in Java that has class type (or
    interface type) is a reference to some instance
    (or it is a null reference). E.g. a variable
    declared
  • A a
  • holds a reference to an instance. The
    objects themselves are behind the scenes in
    Java we can only manipulate pointers
    (references) to them.
  • E.g. a b Only copies a reference, not an
    object.
  • But important to note references to objects and
    arrays are the only kinds of pointer in Java.
    E.g. there are no pointers to fields or array
    elements or local variables.

16
Instance and static members
  • The following terminologies are common. In
  • public class A
  • int x
  • void foo()
  • static int y
  • static void goo()
  • We say
  • x is an or instance variable, or non-static
    field.
  • foo() is an instance method, or non-static
    method.
  • y is a static field, or class variable.
  • goo() is a static method, or class method.

17
Class Loading
  • A Java program is typically written as a class
    with a public, static, void, main() method, as
    follows
  • public class MyProgram
  • public static void main(String args)
  • body of program
  • and started by a command like
  • java MyProgram
  • This command creates a Java Virtual Machine,
    loads the class MyProgram into the JVM, then
    invoke its main() method.
  • As this process unfolds, dependencies on other
    class and interfaces and their supertypes will be
    encountered, e.g. through statements that use
    other classes. The class loader brings in the
    class files for these types on demand. Code is
    loaded, and methods linked, incrementally,
    throughout execution.

18
The CLASSPATH
  • Many people have problems getting the CLASSPATH
    environment variable right.
  • Because all linking is done at run-time, must
    ensure that this environment variable has the
    right class files on it.
  • The class path is a colon-separated
    (semicolon-separated in Windows) list of
    directories and jar files.
  • If the class path is empty, it is equivalent to
    .. But if the class path is not empty, . is
    not included by default.
  • A directory entry means a root directory in which
    class files or package directories are stored a
    jar entry means a jar archive in which class
    files or package directories are stored.

19
Binary Compatibility
  • There is a useful property called
    binary-compatibility between classes. This means
    that (within some specified limits) two class
    files that implement the same public interface
    can be used interchangeably.
  • It also means that if you pick up an
    inappropriate implementation of a given class
    from the CLASSPATH at runtime, things can go
    wrong in an opaque way.

20
Java Native Interface
  • Some methods in a class may be declared as native
    methods, e.g.
  • class B
  • public native long add(int nums)
  • Notice the method add() has the modifier
    native, and the body of the method declaration is
    missing
  • It is replaced by a semicolonsimilar to abstract
    methods in interfaces, etc. But in this case the
    method isnt abstract.
  • The implementation of a native method will be
    given in another language, typically C or C (we
    consider C).
  • Implementing native methods is quite involved.
  • Arguably a good thingit discourages casual use!
    Generally need a good reason for resorting to JNI.

21
A Definition of Java_B_add()
  • JNIEXPORT jlong JNICALL Java_B_add(JNIEnv env,

  • jobject this, jintArray nums)
  • jint cnums
  • int i, n
  • jlong sum 0
  • n (env)-gtGetArrayLen(env, nums)
  • cnums (env)-gtGetIntArrayElements(env,
    nums, NULL)
  • for(i 0 i lt n i)
  • sum cnums i
  • return sum

22
The Invocation API
  • JNI also provides a very powerful mechanism for
    going the other waycalling from a C program into
    Java.
  • First the C program needs to create a JVM
    (initialize all the data structures associated
    with a running JVM), which it does with a
    suitable library call.
  • The standard java command works exactly this
    wayit uses the JNI invocation API to create a
    JVM, and call the main() method of the class
    specified on the command line.

23
The Rest of this Segment
  • Will cover three core topics in advanced Java
  • Multithreaded Programming in Java
  • Java as a multithreaded language Java thread
    synchronization primitives.
  • Network Programming in Java
  • Traditional Java class libraries for sockets,
    URLs.
  • Overview of Java New I/O.
  • Java Servlets and Java Server Pages.
  • Java technologies for Web Applications.
  • Other Java techniques (e.g. Java for XML, Web
    Services) will be introduced as the course
    unfolds.

24
1) Multithreaded Programming in Java
25
Need for Concurrent Programming
  • This course is mostly about distributed
    programming.
  • This is a different discipline from concurrent or
    multithreaded programming, but doing distributed
    programming without understanding concurrent
    programming is error prone.
  • Some frameworks (e.g. EJB) try to enable
    distributed programming while insulating the
    programmer from the difficulties of concurrent
    programming, but eventually you are likely to hit
    concurrency issues.

Non-determinism
Partial failures
Sequential programming
Concurrent programming
Distributed programming
26
Java as a Threaded Language
  • In C, C, etc it is possible to do multithreaded
    programming, given a suitable library.
  • e.g. the pthreads library.
  • Unlike other languages, Java integrates threads
    into the basic language specification in a much
    tighter way.
  • Every Java Virtual Machine must support threads.

27
Features of Java Threads
  • Java provides a set of synchronization primitives
    based on monitor and condition variable paradigm
    of C.A.R. Hoare.
  • Underlying functionality similar to e.g. POSIX
    threads.
  • Syntactic extension for threads (deceptively?)
    small
  • synchronized attribute on methods.
  • synchronized statement.
  • volatile keyword.
  • Other thread management and synchronization
    captured in the Thread class and related classes.
  • But the presence of threads has a wide-ranging
    effect on language specification and JVM
    implementation.

28
Contents of this Lecture
  • Introduction to Java Threads.
  • Mutual Exclusion.
  • Synchronization between Java Threads using wait()
    and notify().
  • Other features of Java Threads.
  • Suggested Exercises

29
Java Thread Basics
30
Threads of Execution
  • Every statement in a Java program is executed in
    a context called its thread of execution.
  • When you start a Java program in the normal way,
    the main() methodand any methods called from
    that methodare executed in a singled out (but
    otherwise ordinary) thread sometimes called the
    main thread.
  • Other threads can run concurrently with the main
    thread. These threads share access to the same
    classes and objects as the main thread, but they
    execute asynchronously, in their own time.
  • The main thread can create new threads these
    threads can create further threads, etc.

31
Creating New Threads
  • Any Java thread of execution (including the main
    thread) is associated with an instance of the
    Thread class. Before starting a new thread, you
    must create a new instance of this class.
  • The Java Thread class implements the interface
    Runnable. So every Thread instance has a method
  • public void run() . . .
  • When the thread is started, the code executed in
    the new thread is the body of the run() method.
  • Generally speaking the new thread ends when this
    method returns.

32
Making Thread Instances
  • There are two ways to create a thread instance
    (and define the thread run() method). Choose at
    your convenience
  • Extend the Thread class and override the run()
    method, e.g.
  • class MyThread extends Thread
  • public void run()
  • System.out.println(Hello from another
    thread)
  • . . .
  • Thread thread new MyThread()
  • Create a separate Runnable object and pass to the
    Thread constructor
  • class MyRunnable implements Runnable
  • public void run()
  • System.out.println(Hello from another
    thread)
  • . . .
  • Thread thread new MyThread(new MyRunnable())

33
Starting a Thread
  • Creating the Thread instance does not in itself
    start the thread running.
  • To do that you must call the start() method on
    the new instance
  • thread.start()
  • This operation causes the run() method to
    start executing concurrently with the original
    thread.
  • In our example the new thread will print the
    message Hello from another thread to standard
    output, then immediately terminate.
  • You can only call the start() method once on any
    Thread instance. Trying to restart a thread
    causes an exception to be thrown.

34
Example Multiple Threads
  • class MyThread extends Thread
  • MyThread(int id)
  • this.id id
  • public void run()
  • System.out.println(Hello from thread
    id)
  • private int id
  • . . .
  • Thread threads new Thread p
  • for(int i 0 i lt p i)
  • threads i new MyThread(i)
  • for(int i 0 i lt p i)
  • threads i.start()

35
Remarks
  • This is one way of creating and starting p new
    threads to run concurrently.
  • The output might be something like (for p 4)
  • Hello from thread 3
  • Hello from thread 4
  • Hello from thread 2
  • Hello from thread 1
  • Of course there is no guarantee of order
    (or atomicity) of outputs, because the threads
    are concurrent.
  • One might worry about the efficiency of this
    approach for large numbers of threads (massive
    parallelism).

36
JVM Termination and Daemon Threads
  • When a Java application is started, the main()
    method of the application is executed in the main
    thread.
  • If the main method never creates any new
    threadsthe JVM keeps running until the main()
    method completes (and the main thread
    terminates).
  • Typically, the java command finishes.
  • If main() creates new threads, by default the JVM
    terminates when all user-created threads have
    terminated.
  • More generally there are system threads executing
    in the background (e.g. threads might be
    associated with garbage collection). These are
    marked as daemon threadsmeaning that they dont
    have the property of keeping the JVM alive. So
    actually the JVM terminates when all non-daemon
    threads terminate.
  • Ordinary user threads can create daemon threads
    by applying the setDaemon() method to the thread
    instance before starting it.

37
Mutual Exclusion
38
Avoiding Interference
  • In any non-trivial multithreaded (or
    shared-memory-parallel) program, interference
    between threads is an issue.
  • Generally interference (or a race condition)
    occurs if two threads are trying to do operations
    on the same variables at the same time. This
    often results in corrupt data.
  • But not always. It depends on the exact
    interleaving of instructions. This
    non-determinism is the worst feature of race
    conditions.
  • A popular solution is to provide some kind of
    lock primitive. Only one thread can acquire a
    particular lock at any particular time. The
    concurrent program can be written so that
    operations on some given variables are only
    performed by threads holding the lock for those
    variables.
  • In POSIX threads, for example, the lock objects
    are called mutexes.

39
Monitors
  • Java adopts a version of monitors, proposed by
    C.A.R. Hoare.
  • Every Java object is created with its own lock
    (and every lock is associated with an
    objectthere is no way to create an isolated
    mutex). In Java this lock is often called the
    monitor lock.
  • Methods of a class can be declared to be
    synchronized.
  • The objects lock is acquired on entry to a
    synchronized method, and released on exit from
    the method.
  • Synchronized static methods need slightly
    different treatment.
  • If methods generally modify the fields (instance
    variables) of the method instance, this leads to
    a natural and systematic association between
    locks and the variables they guard.
  • The critical region is the body of the
    synchronized method.

40
Example use of Synchronized Methods
Thread A
Thread B
call to counter.increment()
// body of synchronized method tmp1 count
count tmp1 1
call to counter.decrement()
Blocked
counter.increment() returns
// body of synchronized method tmp2 count
count tmp2 - 1
counter.decrement() returns
41
Caveats
  • This approach helps to encourage good practices,
    and make multithreaded Java programs less
    error-prone than, say, multithreaded C programs.
  • But it isnt magicit still depends on correct
    identification of the critical regions, to avoid
    race conditions.
  • Concurrent programming is hard, and if you start
    with the assumption Java somehow makes concurrent
    programming easy, you are probably going to
    write some broken programs!

42
Example A Simple Queue
  • public class SimpleQueue
  • public synchronized void add(Object data)
  • if (front ! null)
  • back.next new Node(data)
  • back back.next
  • else
  • front new Node(data)
  • back front
  • public synchronized Object rem()
  • Object result null
  • if (front ! null)
  • result front.data
  • front front.next
  • return result

43
Remarks
  • This queue is implemented as a linked list with a
    front pointer and a back pointer.
  • The method add() adds a node to the back of the
    list the method rem() removes a node from the
    front of the list.
  • The rem() method immediately returns null when
    the queue is empty.
  • The Node class just has a data field (type
    Object) and a next field (type Node).
  • The following slide gives an example of what
    could go wrong without mutual exclusion. It
    assumes two threads concurrently add nodes to the
    queue.
  • In the initial state, Z is the last item in the
    queue. In the final state, the X node is
    orphaned, and the back pointer is null.

44
The Need for Synchronized Methods
Thread A add(X)
null
Z
back
back.next new Node(X)
Thread B add(Y)
null
back.next new Node(Y)
X
Z
null
X
back
Z
null
Y
back back.next
back
null
X
Z
back back.next
null
Y
back
null
X
Z
Corrupt data structure!
null
Y
back
null
45
The synchronized construct
  • The keyword synchronized also appears in the
    synchronized statement, which has syntax like
  • synchronized (object)
  • critical region
  • Here object is a reference to any object. The
    synchronized statement first acquires the lock on
    this object, then executes the critical region,
    then releases the lock.
  • Typically you might use this for the lock object,
    somewhere inside a non-synchronized method, when
    the critical region is smaller than the whole
    method body.
  • In general, though, the synchronized statement
    allows you to use the lock in any object to guard
    any code.

46
Deadlock
  • Deadlock occurs when a group of threads are
    mutually waiting for one another in such a way
    that none can proceed.
  • This happens if there is a cycle of waits-for
    dependencies, e.g.
  • A waits for B, B waits for C, , D waits for A.
  • There are unfortunately many ways this can occur.
    One common situation is if two threads try to
    acquire the same pair of locks in different
    orders, e.g.

Thread A synchronized(x)
synchronized(y)
Thread B synchronized(y)
synchronized(x)
47
Performance Cost of synchronized
  • Acquiring locks introduces an overhead in
    execution of synchronized methods. See, for
    example
  • Performance Limitations of the Java Core
    Libraries,
  • Allan Heydon and Marc Najork (Compaq),
  • Proceedings of ACM 1999 Java Grande Conference.
  • Many of the original utility classes in the Java
    platform (e.g. Vector, etc) were specified to
    have synchronized methods, to make them safe for
    the multithreaded environment.
  • This was probably a mistake newer replacement
    classes (e.g. ArrayList) dont have synchronized
    methodsthe programmer provides synchronization
    as needed, e.g. through wrapper classes.

48
General Synchronization
49
Beyond Mutual Exclusion
  • The mutual exclusion provided by synchronized
    methods and statements is an important category
    of synchronization.
  • But there are other interesting forms of
    synchronization between threads. Mutual exclusion
    by itself is not enough to implement these more
    general sorts of thread interaction (not
    efficiently, anyway).
  • POSIX threads, for example, provides a second
    kind of synchronization object called a condition
    variable to implement more general inter-thread
    synchronization.
  • In Java, condition variables (like locks) are
    implicit in the definition of objects every
    object effectively has a single condition
    variable associated with it.

50
A Motivating Example
  • Consider the simple queue from the previous
    example.
  • If we try to remove an item from the front of the
    queue when the queue is empty, SimpleQueue was
    specified to just return null.
  • This is reasonable if our queue is just meant as
    a data structure buried somewhere in an
    algorithm. But what if the queue is a message
    buffer in a communication system?
  • In that case, if the queue is empty, it may be
    more natural for the remove operation to block
    until some other thread added a message to the
    queue.

51
Busy Waiting
  • One approach would be to add a method that polls
    the queue until data is ready
  • public synchronized Object get()
  • while(true)
  • Object result rem()
  • if (result ! null)
  • return result
  • This works, but it may be inefficient to keep
    doing the basic rem() operation in a tight loop,
    if these machine cycles could be used by other
    threads.
  • This isnt clear cut sometimes busy waiting is
    the most efficient solution.
  • Another possibility is to put a sleep() operation
    in the loop, to deschedule the thread for some
    fixed interval between polling operations. But
    then we lose responsiveness.

52
wait() and notify()
  • In general a more elegant approach is to use the
    wait() and notify() families of methods. These
    are defined in the Java Object class.
  • Typically a call to a wait() method puts the
    calling thread to sleep until another thread
    wakes it up again by calling a notify() method.
  • We will speak of wait() putting a thread to sleep
    inside a particular object, meaning we use the
    condition variable associated with that object.
    The notify() call that subsequently wakes the
    thread must be called on the same object.

53
wait() and notify() II
  • In our example, if the queue is currently empty,
    the get() method would invoke wait(). This
    causes the get() operation to block.
  • Later when another thread calls add(), putting
    data on the queue, the add() method invokes
    notify() to wake up any sleeping thread. The
    original get() call can then return.

54
A Simplified Example
  • public class Semaphore
  • int s
  • public Semaphore(int s) this.s s
  • public synchronized void add()
  • s
  • notify()
  • public synchronized void get() throws
    InterruptedException
  • while(s 0)
  • wait()
  • s--

55
Remarks I
  • Rather than a linked list we have a simple
    counter, which is required always to be
    non-negative.
  • add() increments the counter.
  • get() decrements the counter, but if the counter
    was zero it blocks until another thread
    increments the counter.
  • The data structures are simplified, but the
    synchronization features used here are
    essentially identical to what would be needed in
    a blocking queue (left as an exercise).
  • Some may recognize this as an implementation of a
    classical semaphorean important synchronization
    primitive in its own right.

56
Remarks II
  • wait() and notify() should be used inside
    synchronized methods of the object they are
    applied to.
  • More precisely, the calling thread must hold the
    objects monitor lock.
  • The wait() operation pauses the thread that
    calls it. It also releases the lock that the
    thread holds on the object, for the duration of
    the wait() call.
  • The lock must be claimed again, before continuing
    after the pause.
  • While the lock is temporarily released, another
    synchronized method can proceed.
  • This method may wake up the first, by calling
    notify().

57
Remarks III
  • Several threads can wait() simultaneously in the
    same object.
  • If any threads are waiting in the object, the
    notify() method wakes up exactly one of those
    threads. If no threads are waiting in the
    object, notify() does nothing.
  • Common lore has it that one should always put a
    wait() call in a loop, in case the condition that
    caused the thread to sleep has not been resolved
    when the wait() completes.
  • The logic in the example here doesnt strictly
    require itan if would also work.
  • A wait() method may throw an InterruptedException
    (rethrown by get() in the example). This will be
    discussed later.

58
Another Example
  • public class Barrier
  • private int n, generation 0, count 0
  • public Barrier(int n) this.n n
  • public synchronized void synch() throws
    InterruptedException
  • int genNum generation
  • count
  • if(count n)
  • count 0
  • generation
  • notifyAll()
  • else
  • while(generation genNum)
  • wait()

59
Remarks
  • This class implements barrier synchronizationan
    important operation in shared memory parallel
    programming.
  • It synchronizes n processes when n threads make
    calls to synch() the first n-1 block until the
    last one has entered the barrier.
  • The method notifyAll() generalizes notify(). It
    wakes up all threads currently waiting on this
    object.
  • Many authorities consider use of notifyAll() to
    be safer than notify(), and recommend always to
    use notifyAll().
  • In the example, the generation number labels the
    current, collective barrier operation it is only
    really needed to control the while loop round
    wait().
  • And this loop is only really needed to conform to
    the standard pattern of wait()-usage, mentioned
    earlier.

60
Final Remarks on Synchronization
  • We illustrated with a couple of simple examples
    that wait() and notify() allow various
    interesting patterns of thread synchronization
    (or thread communication) to be implemented.
  • In some sense these primitives are sufficient to
    implement general concurrent programmingany
    pattern of thread synchronization can be
    implemented in terms of these primitives.
  • For example you can easily implement message
    passing between threads (left as an exercise)
  • This doesnt mean these are necessarily the last
    word in synchronization e.g. for scalable
    parallel processing one would like a primitive
    barrier operation more efficient than the O(n)
    implementation given above.

61
Other Features of Java Threads
62
Other Features
  • This lecture isnt supposed to cover all the
    detailsfor those you should look at the spec!
  • But we mention here a few other features you may
    find useful.

63
Join Operations
  • The Thread API has a family of join() operations.
    These implement another simple but useful form
    of synchronization, by which the current thread
    can simply wait for another thread to terminate,
    e.g.
  • Thread child new MyThread()
  • child.start()
  • Do something in current thread
  • child.join() // wait for child thread to
    finish

64
Priority and Name
  • Thread have properties priority and name, which
    can be defined by suitable setter methods, before
    starting the thread, and accessed by getter
    methods.

65
Sleeping
  • You can cause a thread to sleep for a fixed
    interval using the sleep() methods.
  • This operation is distinct fromand less powerful
    thanwait(). It is not possible for another
    thread to prematurely wake up a thread that was
    paused using sleep().
  • If you want to sleep for a fixed interval, but
    allow another thread to wake you beforehand if
    necessary, use the variants of wait() with
    timeouts instead.

66
Deprecated Thread Methods
  • There is a family of methods of the Thread class
    that was supposed to give life-or-death control
    over threads.
  • Experience showed these didnt really work, and
    killing threads is no longer considered
    acceptable in polite society.
  • If you need to interrupt a running thread, you
    should explicitly write the thread it in such a
    way that it pays attention to interrupt
    conditions (see the next slide) and terminates
    itself.
  • If you want to run an arbitrary thread in such a
    way that it can be killed and garbage collected
    by an external agent, you probably need to fork a
    separate process, not a thread.
  • The deprecated methods include stop(), destroy(),
    suspend(), and resume().

67
Interrupting Threads
  • Calling the method interrupt() on a thread
    instance requests cancellation of the thread
    execution.
  • This works in an advisory way the code for the
    thread must explicitly test whether it has been
    interrupted, e.g.
  • public void run()
  • while(!interrupted())
  • do something
  • Here interrupted() is a static method of the
    Thread class.
  • If the interrupted thread is executing a blocking
    operation like wait() or sleep(), the operation
    will throw an InterruptedException.
    Interruptible threads should catch this exception
    and terminate themselves.
  • This mechanism depends on suitable implementation
    of the thread body. The programmer must decide
    at the outset whether it is important that a
    particular thread be responsive to
    interruptsoften it isnt.

68
Thread Groups
  • There is a mechanism for organizing threads into
    groups. This may be useful for imposing security
    restrictions on which threads can interrupt other
    threads, for example.
  • Check out the API of the ThreadGroup class if you
    think this may be important for your application.

69
Thread-Local Variables
  • An object from the ThreadLocal class stores an
    object which has a different, local value in
    every thread.
  • Check the API of the ThreadLocal class for
    details.

70
Volatile Variables
  • Suppose a the value of a variable must be
    accessible by multiple threads, but you decided
    you cant afford the overheads of synchronized
    methods or the synchronized statement.
  • Presumably effects of race conditions are known
    to be innocuous.
  • Java does not guaranteeabsent lock operations
    that force write-back to main memorythat the
    value of a variable written by a one thread will
    be visible to other threads.
  • But if you declare a field to be volatile
  • volatile int myVariable
  • the JVM is supposed to synchronize the value
    of any thread-local (cached) copy of the variable
    with central storagemaking it visible to all
    threadsevery time the variable is updated.
  • The exact semantics of volatile variables and the
    Java memory model in general is still
    controversial, see for example
  • A New Approach to the Semantics of Multithreaded
    Java,
  • Jeremy Manson and William Pugh,
  • http//www.cs.umd.edu/pugh/java/memoryModel/

71
Threads on Symmetric Multiprocessors
  • Most modern implementations of the Java Virtual
    Machine will map Java threads into native threads
    of the underlying operating system.
  • For example these may be POSIX threads.
  • On multiprocessor architectures with shared
    memory, these threads can exploit multiple
    available processors.
  • Hence it is possible to do true parallel
    programming using Java threads within a single
    JVM.
  • See the lectures on Java HPC, cited earlier, for
    examples.

72
2) Network Programming in Java
73
Contents of this Section
  • Basics of network programming in Java
  • Sockets background
  • Socket classes, with simple HTTP examples
  • Internet address classes
  • URL classes
  • Overview of New I/O extensions
  • Efficient data transfer
  • Non-blocking sockets
  • Multiplexing (select)
  • JSSE elements

74
Sockets, Addresses and URLs
75
Sockets
  • Sockets first appeared in BSD UNIX (designed by
    Bill Joylater a designer of Java) circa 1982.
  • Cross-protocol API for networking. Original
    implementation supported protocols including
  • TCP/IP
  • Xerox NS
  • Local UNIX inter-process communication.
  • Today available in all variants of UNIX/Linux,
    and in Windows through the WinSock API.
  • Directly support a client/server architecture.
  • Support connection-oriented protocols like TCP,
    and connectionless protocols like UDP.

76
BSD Socket Calls
Network
Server
Client
socket() create socket
socket() create socket
bind() name socket
connect()
listen()
accept() accept connection
write() send request
read() get request
. . . process request . . .
write() send reply
read() get reply
77
Port Numbers
  • The bind() call on the server side establishes a
    well-known address for the listening socket.
  • In the case of an TCP/IP socket the important
    part of this is the port number.
  • A port number is an integer between 0 and 64K.
  • On any given host, only one server socket can be
    listening on a particular port at a particular
    time.
  • In UNIX, port numbers below 1024 can only be used
    by a privileged user (the super-user). Any user
    can create a server socket listening on higher
    ports.
  • Low port numbers are used by standard services,
    e.g.
  • 23 is the default port number for telnet
  • 80 is the default port number for HTTP servers

78
Making a Connection
  • The client makes a connect() call, specifying the
    remote host IP address, and the port number for
    the server socket it wants to connect to.
  • Meanwhile the server is waiting on an accept()
    call on the server socket.
  • When the connection is established, the accept()
    call completes, returning a reference to a new
    socket.
  • Data is subsequently exchanged through the socket
    pair consisting of the client socket, and the new
    socket on the server, returned by the accept()
    call.

79
Sockets in Java
  • Using sockets from C is traditionally quite hard.
    The arguments of the BSD socket functions are
    complex.
  • Perhaps in part because of the historical need to
    support multiple protocols.
  • Luckily the API has been greatly simplified in
    the Java binding for sockets.
  • The associated classes are in the package
    java.net.

80
Java Sockets from the Client Side
  • A Java program can open a socket connection in
    one step using a constructor of the Socket class
  • Socket t new Socket(hostName,
    port)
  • Here hostName is a string, like
    grid2004.org, and port is an integer, like 80.
  • This constructor subsumes the socket() and
    connect() calls in the BSD API.
  • The Socket class has methods getInputStream() and
    getOutputStream(), returning Java stream objects
    that swap data between the connected socket pair.
  • The connection is bi-directional both client an
    server can read and write.

81
A Simple Client
  • import java.io.
  • import java.net.
  • public class TrivialBrowser
  • public static void main(String args)
    throws IOException
  • Socket s new Socket(www.grid2004.o
    rg, 80)
  • PrintWriter out new PrintWriter(
  • new OutputStreamWriter(s.ge
    tOutputStream()))
  • out.print("GET /spring2004/index.ht
    ml HTTP/1.1\r\n")
  • out.print("Host www.grid2004.org\r\n
    \r\n")
  • out.flush()
  • BufferedReader in new
    BufferedReader(
  • new InputStreamReader(s.ge
    tInputStream()))
  • String line
  • while((line in.readLine()) !
    null)
  • System.out.println(line)

82
Remarks
  • This implements a (drastically restricted) Web
    client.
  • Cut and paste this slide, compile and run the
    code. It prints out the HTML source for the
    course home page.
  • It connects to port 80 on the server (the HTTP
    port).
  • It gets an output stream to write to the socket
    using getOuputStream().
  • It sends an HTTP GET request on the stream,
    specifying the file it1spring01/index.html
    relative to the servers document root.
  • It gets an input stream to read from the socket
    using getInputStream().
  • It copies lines from the socket connection to the
    console.

83
Java Sockets from the Server Side
  • The BSD operations socket(), bind() and listen()
    for a server-side socket are subsumed in a
    constructor for the ServerSocket class
  • ServerSocket s new
    ServerSocket(port)
  • Here port is the integer port number, such as
    80 (if you are writing a Web server), on which
    the server will listen.
  • Next the Java server will call the accept()
    method and wait for clients to connect to it.
    accept() returns an ordinary socket, completing
    the socket-pair for the connection
  • Socket connection s.accept()
  • After processing the request, the client goes
    back to waiting on accept(), for new client
    requests.
  • Real servers typically fork a thread or process
    to deal with the request, and return immediately
    to waiting for the next client connection.

84
A Simple Server
  • public static void main(String args) throws
    Exception
  • ServerSocket server new
    ServerSocket(8080)
  • while(true)
  • Socket sock server.accept()
  • BufferedReader in new
    BufferedReader(
  • new InputStreamReader(sock
    .getInputStream())
  • String header in.readLine()
  • . . . Skip over any other lines in
    request packet . . .
  • String fileName path component
    from 2nd field of header
  • DataOutputStream out
  • new DataOutputStream(sock.getO
    utputStream())
  • if( file fileName exists )
  • byte bytes contents of
    local file fileName
  • out.writeBytes(HTTP/1.0 200
    OK\r\n)
  • out.writeBytes(Content-Length
    bytes.length \r\n)
  • out.writeBytes(Content-Type
    text/html\r\n\r\n)
  • out.write(bytes)
  • else Send HTTP error status

85
Remarks
  • This implements a (drastically restricted) Web
    server.
  • It creates a server socket listening to port 8080
    on the local host.
  • It gets a socket connection from a client using
    the accept() method, and then gets the input
    stream from the socket using getInputStream().
  • We handle only GET requests the second field
    will normally be the file name (preceded by /).
  • It reads the file (assuming . as document root)
    and writes it to the output stream of the socket,
    in HTTP.
  • A realistic server would probably spawn a new
    thread to deal with each transaction. The main
    loop would return immediately to waiting on
    accept().

86
Other Features of java.net sockets
  • The Socket and ServerSocket classes provide a
    bunch of inquiry methods to determine the socket
    state.
  • But there arent too many more operations one can
    actually perform on sockets
  • One notable thing is setting a time out for I/O
    operations.
  • Notable things you cant do include I/O in
    non-blocking mode, and any kind of select
    functionality.
  • These important features werent added until J2SE
    1.4, in the java.nio packages.
  • In unaugmented java.net sockets, the closest you
    can come is to execute socket operations in
    dedicated threads.

87
Internet Addresses
  • The class java.net.InetAddress bundles together
    various useful functions on Internet address
  • DNS lookup, reverse name resolution, etc.
  • Example methods
  • static InetAddress getByName(String host)
  • static InetAddress getByAddress(byte addr)
  • byte getAddress
  • String getCanonicalHostName()
  • static InetAddress getLocalHost()
  • InetAddress objects can be passed to the
    constructors of socket classes.

88
URL Objects
  • Instead of explicitly opening a socket connection
    to a Web server, a client can read information
    using the higher level URL class.
  • A constructor takes a URL string and creates a
    URL object
  • URL url
  • new URL(http//www.grids2004.org/spring200
    4/)
  • This constructor may throw a MalformedURLException
    .
  • This class is mostly (only?) useful for clients.

89
Reading a File Using a URL Object
  • Now if url is a URL object, the resource can be
    read by opening a stream on the URL
  • BufferedReader in
  • new BufferedReader(
  • new InputStreamReader(url.openStream(
    )))
  • This example creates a character stream that can
    be read like any other.

90
URL Connection Objects
  • A class java.net.URLConnection provides
    additional functionality on URLs. A
    URLConnection is created by the openConnection()
    method
  • URLConnection connection url.openConnection()
  • Methods on connection allow to return fields from
    the HTTP header
  • String getContentType()
  • int getContentLength()
  • . . .
  • You can also open an InputStream or OutputStream
    on a URL connection. The latter is used for HTTP
    POST requests.

91
UDP in Java
  • So far discussed use of Java sockets for TCP.
  • The User Datagram Protocol is an alternative
    which is neither connection-oriented nor
    reliable.
  • It transports datagrams messages of fixed
    (limited) size.
  • Messages may occasionally be lost they may also
    be delivered out of order.
  • But for applications that dont need strong
    guarantees it can be faster than TCP, e.g. the
    Internet Domain Naming Service is implemented
    over UDP.
  • Finally, you have to use UDP if you want to
    exploit IP multicast.

92
A UDP Message Producer
  • import java.net.
  • public class UDPProducer
  • public static void main(String args)
    throws java.io.IOException
  • DatagramSocket sock new
    DatagramSocket()
  • InetAddress addr InetAddress.getByName(
    "grids.ucs.indiana.edu")
  • int port 3516
  • for(int i 0 i lt 10 i)
  • String message "message " i
  • byte data message.getBytes()
  • DatagramPacket packet
  • new
    DatagramPacket(data, data.length, addr, port)
  • sock.send(packet)

93
A UDP Message Consumer
  • import java.net.
  • public class UDPConsumer
  • public static void main(String args)
    throws java.io.IOException
  • int port 3516
  • DatagramSocket sock new
    DatagramSocket(port)
  • byte buffer new byte 65536
  • while(true)
  • DatagramPacket packet
  • new DatagramPacket(buffer,
    buffer.length)
  • sock.receive(packet)
  • String message
  • new String(packet.getData(),
    0, packet.getLength())
  • System.out.println(message)

94
Java New I/O
95
NIO New I/O
  • Prior to the J2SE 1.4 release of Java, I/O had
    become a performance bottleneck.
  • The old java.io stream classes had too many
    software layers to be fast.
  • No way to multiplex data from multiple sources
    without incurring thread context switches
  • No way to exploit modern OS tricks for high
    performance I/O, like memory mapped files.
  • New I/O changed that.

96
Features of New I/O
  • New I/O provides
  • A hierarchy of dedicated buffer classes that
    allow data to be moved from the JVM to the OS
    with minimal memory-to-memory copying, and
    without overheads like switching byte
    ordereffectively give Java a window on system
    memory.
  • A unified family of channel classes that allow
    data to be fed directly from buffers to files and
    sockets, without going through the slow old
    stream classes.
  • Non-blocking I/O on sockets.
  • A family of classes to directly implement
    selection (or readiness testing, or multiplexing)
    over a set of channels.
  • NIO also provides file locking for the first time
    in Java.

97
References
  • The Java NIO software is part of J2SE 1.4 and
    later, from
  • http//java.sun.com/j2se/1.4
  • Online documentation is at
  • http//java.sun.com/j2se/1.4/nio
  • There is an authoritative book from OReilly
  • Java NIO, Ron Hitchens, 2002

98
New I/O Buffers
99
Buffers
  • A Buffer object is a container for a fixed amount
    of data.
  • It behaves something like a byte array, but is
    encapsulated so that the internal storage may be
    a block of system memory.
  • Adding data to, or getting it from, a buffer can
    be a very direct way of getting information
    between a Java program and the underlying
    operating system.
  • All the I/O operations in New I/O operate on
    these buffer objects.

100
The java.nio.Buffer Hierarchy
101
The ByteBuffer Class
  • The most important buffer class in practice is
    the ByteBuffer class. This represents a
    fixed-size vector of primitive bytes.
  • The storage used internally by the buffer class
    is called the backing store.
  • This backing store can either be an ordinary Java
    array, or a block of system memory.
  • If it is system memory, the buffer is called a
    direct buffer.
  • Think of system memory as meaning something
    like a C array allocated by malloc(). It is not
    memory managed by the JVM, subject to garbage
    collection, etc.

102
Creating Buffers
  • There are various factory methods that can be
    used to create a new ByteBuffer, including
  • ByteBuffer wrap(byte array)
  • ByteBuffer allocate(int capacity)
  • ByteBuffer allocateDirect(int
    capacity)
  • These are all static methods of the ByteBuffer
    class
  • wrap() creates a ByteBuffer backed by the Java
    array provided by the caller.
  • allocate() creates a ByteBuffer backed by an
    anonymous Java array, size capacity.
  • allocateDirect() creates a direct ByteBuffer,
    backed by capacity bytes of system memory.

103
Examples
  • import java.nio.
  • public class CreateBuffers
  • public static void main(String args)
  • int BUF_SIZE 1024
  • byte myBacking new byte BUF_SIZE
  • ByteBuffer buffer1 ByteBuffer.wrap(myBac
    king)
  • // Uses array myBacking for
    storage.
  • ByteBuffer buffer2 ByteBuffer.allocate(B
    UF_SIZE)
  • // Uses buffer2.array() for
    storage.
  • ByteBuffer buffer3 ByteBuffer.allocateDi
    rect(BUF_SIZE)
  • // Uses inaccessible system memory
    for storage.

104
ByteBuffer Reads and Writes
  • Has a family of put() and get() methods for
    writing and reading the buffer, e.g.
  • byte get() // Get the next byte in
    the buffer
  • get(byte dst) // Get the next block of
    bytes
  • put(byte b) // Write b to the next
    position in buffer
  • put(byte src) // Write block starting at
    next position
  • I omitted the some of the return types to avoid
    confusion. These methods typically return a
    reference the original possibly modifiedbuffer.
  • The put() and get() operations shown above are
    all relative operations they get data from, or
    insert data into, the buffer, starting at the
    current position in
Write a Comment
User Comments (0)
About PowerShow.com