Chapter 8 Three Interfaces Cloneable Serializable and Runnable
Chapter 8 Three Interfaces: Cloneable, Serializable, and Runnable 1
Cloning objects • To clone an object is to make an exact copy of it. • A cloned object should be independent of the source object from which it is cloned. • An object is cloned by invoking its method clone(), which has protected scope in Object. 2
Cloning basics • To enable cloning, a class declares the clone() method inherited ultimately from Object as public. In Object, the method is protected. • A public override of the inherited clone() method should throw a Clone. Note. Supported. Exception. 3
Cloning basics • If a class’s fields include object or array references, the clone() override must ensure that, after the cloning, the source and target objects are independent. • Object’s method clone()simply copies references so that a clone source and target wind up with references to the same object. 4
Cloning basics • Arrays can be cloned. A cloned array has the same number of elements and the same contents as the source array. • Cloning can be disabled by having a public override of clone()explicitly throw a Clone. Not. Supported. Exception. 5
Serialization basics • Serialization is the process of transforming an in-memory object to a byte stream. • Deserialization is the inverse process of reconstructing an object from a byte stream to the same state in which the object was previously serialized. • “Serializing out” and “serializing in” are also used. 6
Serialization basics • The requirements for serialization are straightforward: – Only class instances rather than primitive types can be serialized. – For an object to be serializable, its class or some ancestor must implement the empty Serializable interface. – An empty interface is called a marker interface. 7
Serialization basics • The syntax for serialization is straightforward: – An object is serialized by writing it to an Object. Output. Stream. – An object is deserialized by reading it from an Object. Input. Stream. 8
Serialization code File. Output. Stream out = new File. Output. Stream( “save. ser” ); Object. Output. Stream oos = new Object. Output. Stream( out ); oos. write. Object( new Date() ); oos. close(); 9
Deserialization code File. Input. Stream in = new File. Input. Stream( “save. ser” ); Object. Input. Stream ois = new Object. Input. Stream( in ); Date d = (Date) ois. read. Object(); ois. close(); 10
Object graphs • If an object has references to other objects or arrays, the entire object graph is serialized when the object is serialized. – The object graph consists of the object directly serialized any other objects or arrays to which the object has direct or indirect references. 11
Nonserializable superclasses • If a serializable class C has a nonserializable superclass S, instances of C still can be serialized if S has an accessible noargument constructor. – S’s no-argument constructor is invoked automatically during deserialization to construct the “S-part” of the deserialized object. 12
Serialization and primitive types • Technically, primitive types cannot be serialized or deserialized. However, the Object. Output. Stream implements the Data. Output interface, which declares methods such as write. Int to write primitive types to streams. • Object. Input. Stream implements Data. Input for reading primitive types. 13
transient and static fields • A field marked as transient is not impacted by serialization. – During deserialization, transient fields are restored to their default values (e. g. , transient numeric fields are restored to zero). • static fields are not impacted by serialization. 14
Customization • Serialization and deserialization can be customized by providing private callback methods named write. Object and read. Object, respectively. • The Externalizable interface can be implemented by classes that need to have complete control over serialization and deserialization. 15
Cautionary notes • The same object should not be repeatedly serialized to the same stream. • A class should not be redefined in between the serialization and deserialization of its instances. • Classes that need to disable serialization can throw a Not. Serializable. Exception in the private callback write. Object. 16
Multithreading basics • A thread of control is a sequence of instructions that execute in the JVM. • Java programs begin as single-threaded programs but can become multithreaded by constructing and starting Threads. • A program can have arbitrarily many threads of execution. 17
Multithreading basics • A typical code segment to construct and start a thread is Thread t = new Thread( this ); t. start(); where this refers to a Runnable target. • A runnable target is an object whose class implements the Runnable interface. 18
Multithreading basics • The Runnable interface declares a single method public void run(); • The run() method is a pure callback; that is, the programmer defines but never invokes run(). • The system invokes run()to execute a thread; the programmer invokes start(). 19
Multithreading basics • If Thread is extended, the subclass should override the inherited run(), which returns immediately. – The override of run() provides whatever code a thread should execute. – A thread stops permanently once it returns from run(). – A stopped thread cannot be restarted. 20
Thread priorities • If a program has multiple threads of the same priority executing, then thread execution is interleaved in unpredictable ways. • Threads have priorities ranging from MIN_PRIORITY through MAX_PRIORITY, which are numeric constants. 21
Thread priorities • Although the range for thread priorities is not standardized, typical values are – 1 for MIN_PRIORITY. – 5 for NORM_PRIORITY. – 10 for MAX_PRIORITY. • The JVM uses priority-based, preemptive scheduling: a higher priority thread always preempts a lower priority thread. 22
Thread priorities • If two threads T 1 and T 2 are started, but T 2 has a higher priority than T 1, then T 2 preempts T 1 if T 1 is executing; and T 1 does not execute again until T 2 stops. • A thread of a given priority P starts another thread of the same priority. The set. Priority can change a thread’s priority before thread is started. 23
User and daemon threads • Threads are of two types: user threads and daemon threads. • A program continues to run so long as at least one user thread is alive. By contrast, a daemon thread by itself cannot sustain a program’s execution. • The garbage collector runs as a daemon thread. 24
User and daemon threads • A user thread constructs a user thread; a daemon thread constructs a daemon thread. • The set. Daemon method can be invoked to change a thread’s daemon status before thread is started. • Daemon threads are “helper” threads for user threads. 25
Thread states • A thread is one of four possible states: – Initial state. A newly constructed thread is in its initial state until started. – Runnable state. Once started, a thread is runnable or “alive” until the thread stops. – Blocked state. A thread can be blocked in various ways, e. g. , by sleeping or waiting. A blocked thread becomes runnable once unblocked. 26
Thread states – Stop state. A thread enters the stop state if it returns from run() or the deprecated stop() method is invoked on it. • Once stopped, a thread cannot be restarted. • If a thread needs to run indefinitely, the run() method can have an infinite loop in it. 27
Thread groups • Every thread belongs to a Thread. Group, which is either explicitly named or a default thread group. • Thread groups are a convenience. For instance, if several threads belong to a group, then set. Daemon could be invoked on the group as a whole instead of on each individual thread. 28
Thread synchronization • Suppose that threads T 1 and T 2 read and write a shared field. In this case, T 1 and T 2 need to be synchronized so that, for example, T 1 is not reading while T 2 is writing. (Write operations are not “atomic” but rather consist of (a) evaluating the assignment value and (b) assigning the value to the target. ) 29
Thread synchronization • Java provides a lock construct to ensure single-threaded execution of critical section code, that is, code to which threads must have mutually exclusive access. • The synchronized keyword can be used to lock a block of code within a method or an entire method. 30
Thread synchronization • The code segment synchronized( this ) { // single-threaded execution } shows the syntax of a synchronized block. The lock is the object to which this refers. • A synchronized block requires an object as a lock. 31
Thread synchronization • The code segment synchronized void get. Chopsticks() { //. . . single-threaded execution } shows the syntax for a synchronized method. The implicit lock is the object to which this refers. 32
Thread synchronization • A thread that gains a lock can invoke wait to release the lock until a subsequent invocation of notify or notify. All by the thread that gains the lock. – Invocation of wait is guaranteed to be “atomic” or “noninterruptable. ” – A thread that invokes wait simultaneously releases the lock and goes into a waiting state. 33
Thread synchronization • notify awakens an arbitrary waiting thread, whereas notify. All awakens all waiting threads. – Either method can be invoked even if no threads happen to be waiting at the time. – The methods awaken only threads that went into a wait state beforehand. – The methods are typically invoked as the last statement in a synchronized block or method. 34
Deadlock • Synchronization locks open the possibility of deadlock, a condition that involves at least two threads. In deadlock, each thread holds a lock and releases it only when the other threads release their locks. • The JVM does not detect, prevent, or recover from deadlock. The programmer must avoid deadlock. 35
The join method • Suppose that t 1 and t 2 refer to two threads and that the t 1 -thread invokes t 2. join(); // wait for t 2 to stop The invocation causes the t 1 -thread to wait until the t 2 -thread stops. • The join method is a powerful construct for thread synchronization. 36
Deprecated thread methods • The stop method has been deprecated. The preferred way to stop a thread is to have thread return from run(). – A stopped thread releases any held locks. • The suspend and resume methods have been deprecated because suspend is deadlock-prone and resume is used only in conjunction with suspend. 37
Critical section problems • Solutions to critical section problems are judged on four criteria. The synchronization mechanism in Java helps satisfy two of the four criteria. 38
Critical section problems • The four criteria are: – Progress. If a critical section is unlocked, a thread should be able to enter it. The synchronized construct ensures this behavior. – Mutual exclusion. At most one thread can hold a lock only a critical section. The synchronized construct ensures this behavior. 39
Critical section problems – Starvation. None of the threads trying to enter a critical section should be permanently prevented from doing so. The synchronized construct does not prevent starvation. – Fairness. Each of N contending threads should enter the critical section roughly the same amount of time. The synchronized construct does not ensure fairness. 40
- Slides: 40