Concurrent, Real-Time and Distributed Programming in Java
FOCUS SERIES Jean-Charles Pomerol Concurrent, Real-Time and Distributed Programming in Java Threads, RTSJ and RMI Badr Benmammar
First published 2018 in Great Britain and the United States by ISTE Ltd and John Wiley & Sons, Inc. Apart from any fair dealing for the purposes of research or private study, or criticism or review, as permitted under the Copyright, Designs and Patents Act 1988, this publication may only be reproduced, stored or transmitted, in any form or by any means, with the prior permission in writing of the publishers, or in the case of reprographic reproduction in accordance with the terms and licenses issued by the CLA. Enquiries concerning reproduction outside these terms should be sent to the publishers at the undermentioned address: ISTE Ltd John Wiley & Sons, Inc. 27-37 St George s Road 111 River Street London SW19 4EU Hoboken, NJ 07030 UK USA www.iste.co.uk www.wiley.com ISTE Ltd 2018 The rights of Badr Benmammar to be identified as the author of this work have been asserted by him in accordance with the Copyright, Designs and Patents Act 1988. Library of Congress Control Number: 2017957888 British Library Cataloguing-in-Publication Data A CIP record for this book is available from the British Library ISSN 2051-2481 (Print) ISSN 2051-249X (Online) ISBN 978-1-78630-258-8
Contents List of Acronyms.... Introduction... vii ix Chapter 1. Introduction to Threads in Java... 1 1.1. Processes versus threads... 1 1.2. Concurrent computing... 2 1.3. Thread creation... 3 1.4. Types of thread... 4 1.5. Monotask versus multitask... 5 1.6. Different states of a thread... 13 1.7. Lifecycle of a thread... 13 1.8. A few notes concerning threads... 16 1.8.1. Two threads without using sleep... 16 1.8.2. Time allocation between two threads... 17 1.8.3. Priority between threads... 19 1.9. Programming a task: Timer and TimerTask... 21 1.9.1. By specifying an initial delay... 21 1.9.2. With an initial delay and periodicity... 23 Chapter 2. Thread Synchronization... 27 2.1. Synchronization upon termination: join() method... 27 2.2. Resource in mutual exclusion: synchronized modifier... 30 2.3. Shared variables: internal class... 33 2.4. The problem with mutual exclusions... 35 2.5. Synchronized block... 36 2.6. Synchronized instance method... 41 2.7. Shared variables: class variable... 43
vi Concurrent, Real-Time and Distributed Programming in Java 2.8. Synchronization between threads... 45 2.8.1. Wait and notifyall... 45 2.8.2. Wait and notify... 48 2.9. Classic Producer Consumer pattern... 51 2.10. Semaphore in Java... 54 2.10.1. Before Java 1.5... 55 2.10.2. After Java 1.5... 57 Chapter 3. Real-Time Systems and Real-Time Java... 61 3.1. Real-time systems... 61 3.1.1. Definition... 61 3.1.2. Examples of real-time operating systems... 62 3.1.3. Types of real-time... 62 3.1.4. Architecture... 63 3.1.5. Task ordinance with priorities... 63 3.2. Java in real-time... 65 3.2.1. RTSJ (Real-Time Specification for Java)... 65 3.2.2. Implementations... 67 Chapter 4. Distributed Programming in Java... 71 4.1. Definition of a distributed application... 71 4.2. Communication in a distributed application... 72 4.2.1. Low-level communication: socket... 72 4.2.2. High-level communication: middleware... 89 Appendix... 127 Bibliography... 155 Index... 157
List of Acronyms API CNI CORBA DCOM DGC FIFO GC GCC GCJ GNU IIOP IP J2SE J2EE J2ME Application Programming Interface Cygnus Native Interface Common Object Request Broker Architecture Distributed Component Object Model Distributed Garbage Collection First In, First Out Garbage Collector GNU Compiler Collection GNU Compiler for Java GNU s Not Unix Internet Inter-ORB Protocol Internet Protocol Java 2 Standard Edition Java 2 Enterprise Edition Java 2 Micro Edition
viii Concurrent, Real-Time and Distributed Programming in Java JDK JNI Java SE Development Kit Java Native Interface JRMP JSSE JVM KVM OSI PCP PIP RMI RMIC RPC RRL RTSJ SSL TCP TLS UDP URL WinCE Java Remote Method Protocol Java Secure Socket Extension Java Virtual Machine Kilo VM Open Systems Interconnection Priority Ceiling Protocol Priority Inheritance Protocol Remote Method Invocation RMI Compiler Remote Procedure Call Remote Reference Layer Real-Time Specification for Java Secure Sockets Layer Transmission Control Protocol Transport Layer Security User Datagram Protocol Uniform Resource Locator Windows Embedded Compact
Introduction This book constitutes an introduction to real-time and distributed concurrent computing, using Java object-oriented language as a support tool for describing algorithms. It describes in particular the synchronization mechanisms (in cooperation and in competition) and data-sharing mechanisms (internal class, static type variables) between threads in Java. We then discuss the use of Java for real-time applications. Subsequently, a presentation of RTSJ (Real-Time Specification for Java) is also introduced in this book. Finally, a presentation of distributed computing can also be found. We focus in particular on low-level communication using TCP Sockets and high-level communication using Java RMI (Remote Method Invocation) middleware. The book also contains an appendix including a set of practical application exercises in relation to the theme of the book. Knowledge of Java language is a prerequisite to properly understanding this book.
1 Introduction to Threads in Java 1.1. Processes versus threads The operating system is tasked with allocating the necessary resources (memory, processing time, inputs/outputs) to the processes and ensuring they do not interfere with one another (isolation) [TAN 01]. This principle is illustrated in the following example in which variable a is defined in two different classes. When executing both classes, the two allocated memory zones for this variable are completely isolated. Figure 1.1. Isolation between processes Concurrent, Real-Time and Distributed Programming in Java: Threads, RTSJ and RMI, First Edition. Badr Benmammar. ISTE Ltd 2018. Published by ISTE Ltd and John Wiley & Sons, Inc.
2 Concurrent, Real-Time and Distributed Programming in Java Most operating systems offer a distinction between: Heavy-weight processes: supposedly completely separate from one another. Light-weight processes (threads): which share a memory space (as well as other resources) in common. DEFINITION 1. A thread is a string of code capable of executing alongside other processes. Threads do not execute at the same time but rather using shared time, this is why it is important that a thread always gives others a chance to execute. The diagram below shows the execution and latency times for four different threads. Figure 1.2. Execution and latency times of four different threads 1.2. Concurrent computing A concurrent programming language must allow the following: creation of threads; sharing data between threads; synchronization among threads: controlling the task execution order depending on the two following models:
Introduction to Threads in Java 3 - Competition synchronization: when more than one thread is using the same resource. There must then be a system for mutual exclusion in order to avoid processes interfering with each other. - Cooperation synchronization: when one thread waits for another to finish executing before starting its own execution. 1.3. Thread creation There are two ways to create a thread in Java: A class derived from java.lang.thread: - The java.lang.thread implements Runnable class. - Thread extends Object implements Runnable public class. - The Thread class must implement the run() method. - The daughter class inherits the run() method. A class that implements the Runnable interface: - The class must implement the run() method. Now, a question arises: which solution should we choose? Method 1: subclassing Thread: - When parallelizing a class which does not inherit from another class (autonomous class). - Note: simple inheritance in java. - extends Thread or implements Runnable, either way. Method 2: implement Runnable: - When a superclass is imposed. - Example, case involving applets: public class MyThreadApplet extends Applet implements Runnable { - Only implements Runnable is valid.
4 Concurrent, Real-Time and Distributed Programming in Java Let us look at the code: Method 1: subclassing Thread class A extends Thread { A ( ) {... // The constructor... public void run ( ) {... // What the Thread does A p1 = new A( ); // Creation of thread p1 p1.start(); // Starts the thread and executes p1.run() Method 2: class that implements Runnable class B implements Runnable { B ( ) {... // Constructor... public void run() {... // What the Thread does B p = new B( ); Thread p2 = new Thread(p);... p2.start(); // Starts the thread and executes p.run() 1.4. Types of thread Two types of thread exist: User threads: this type of thread s activity is time-restricted, meaning its scenario is a process which ends after a certain amount of time. The JVM functions as long as there are user threads being executed. Daemon threads: threads that execute in the background as long as the program is running. Daemon threads are only there to serve user threads. The JVM stops if there are only daemons.
Introduction to Threads in Java 5 Examples: syntax coloring in editors, garbage collectors (DestroyJavaVM), etc. public final boolean isdaemon() in the Thread class to determine the thread s type. public final void setdaemon (boolean) of the Thread class indicates whether the thread will be a daemon or not (user thread by default). It must be called before the thread starts using the start() command. Use setdaemon in the constructor. Example: clock thread running in the background. Clock class extends Thread { public clock () { setdaemon (true); public void run () { while (true) { try {Thread.sleep (300) ; catch (InterruptedException e) { System.out.println ("tip"); // end while // end run public static void main(string arg[]){ A p1 = new A( ); p1.start(); // end main // end class 1.5. Monotask versus multitask To illustrate multitask, let us begin by presenting a monotask execution. In the following example, a parrot (Parrot0.java) converses in monotask with the primary program (ChatAndLaunchTheParrot0.java): class ChatAndLaunchTheParrot0 { public static void main(string args[]) { Parrot0 parrot = new Parrot0 ("coco",4);
6 Concurrent, Real-Time and Distributed Programming in Java blabla(); blabla(); parrot.run (); for (int n=0; n<3; n++) { try {Thread.sleep(1000); catch (InterruptedException e) { System.out.println (e.getmessage ()); System.exit(1); blabla (); // end main private static void blabla() { System.out.println("blabla"); // end class class Parrot0 { private String cri = null; private int fois = 0; public Parrot0 (String s, int i) { cri = s; fois = i; public void run () { for (int n=0; n<fois; n++) { try {Thread.sleep (1000); catch (InterruptedException e) { System.out.println(e.getMessage()); System.exit(1); System.out.println (cri); // end for // end run // end class Executing the previous code results in the following: blabla blabla
Introduction to Threads in Java 7 coco coco coco coco blabla blabla blabla Nothing special, the primary program talks, passes to the parrot s run and the execution ends with the three blabla of the primary program. To perform the multitask, a modification of the previous code is necessary. We will perform this in two different ways. Extending the Thread class: class ChatAndLaunchTheParrot2{ public static void main(string args[]) { Parrot2 parrot = new Parrot2 ("coco",10); parrot.start(); for (int n=0; n<10; n++) { try { Thread.sleep(1000); catch(interruptedexception e) { blabla(); private static void blabla() { System.out.println("blabla"); class Parrot2 extends Thread{ private String cri = null; private int fois = 0;