Java Multi Threading
Java Multi Threading
INPUT/OUTPUT:
• Programs cannot accomplish their goals without accessing external data. Data is retrieved
from an input source. The results of a program are sent to an output destination. In Java, these
sources or destinations are defined very broadly.
• For example, a network connection, memory buffer, or disk file can be manipulated by the
Java I/O classes.
• Although physically different, these devices are all handled by the same abstraction: the
stream.
• A stream is a logical entity that either produces or consumes information. A stream is linked
to a physical device by the Java I/O system. All streams behave in the same manner, even if
the actual physical devices they are linked to differ.
Note:
• Although the main thread is created automatically when your program is started, it can be
controlled through a Thread object.
• To do so, you must obtain a reference to it by calling the method currentThread( ), which is a
public static member of Thread.
Its general form is shown here:
– static Thread currentThread( )
• This method returns a reference to the thread in which it is called. Once you have a reference
to the main thread, you can control it just like any other thread.
Example program of Main Thread:
• The sleep( ) method causes the thread from which it is called to suspend execution for the
specified period of milliseconds. Its general form is shown here:
static void sleep(long milliseconds) throws InterruptedException
• The number of milliseconds to suspend is specified in milliseconds. This method may throw
an InterruptedException.
• The sleep( ) method has a second form, shown next, which allows you to specify the period in
terms of milliseconds and nanoseconds:
static void sleep(long milliseconds, int nanoseconds) throws InterruptedException
• This second form is useful only in environments that allow timing periods as short as
nanoseconds.
• You can obtain the name of a thread by calling getName( ).
These methods are members of the Thread class and are declared like this:
• final void setName(String threadName)
• final String getName( )
OUTPUT:
New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
One: 5
Two: 5
Three: 5
One: 4
Two: 4
Three: 4
One: 3
Three: 3
Two: 3
One: 2
Three: 2
Two: 2
One: 1
Three: 1
Two: 1
One exiting.
Two exiting.
Three exiting.
Main thread exiting.
4.2.1 File
• Files are a primary source and destination for data within many programs.
• Although there are severe restrictions on their use within applets for security reasons, files are
still a central resource for storing persistent and shared information.
• A directory in Java is treated simply as a File with one additional property—a list of filenames
that can be examined by the list( ) method.
File(String directoryPath)
File(String directoryPath, String filename)
File(File dirObj, String filename)
File(URI uriObj)
directoryPath It is the path name of the file, filename is the name of the file or
subdirectory
dirObj It is a File object that specifies a directory
uriObj It is a URI object that describes a file.
• The following example creates three files: f1, f2, and f3.
• The first File object is constructed with a directory path as the only argument.
• The second includes two arguments—the path and the filename.
• The third includes the file path assigned to f1 and a filename; f3 refers to the same file as f2.
OUTPUT:
File Name: COPYRIGHT
Path: /java/COPYRIGHT
Abs Path: /java/COPYRIGHT
Parent: /java
exists
is writeable
is readable
is not a directory
is normal file
is absolute
File last modified: 812465204000
File size: 695 Bytes
• Most of the File methods are self-explanatory. isFile( ) and isAbsolute( ) are not.
• isFile( ) returns true if called on a file and false if called on a directory. Also, isFile( ) returns
false for some special files, such as device drivers and named pipes, so this method can be
used to make sure the file will behave as a file.
• The isAbsolute( ) method returns true if the file has an absolute path and false if its path is
relative.
• Here, the filename specified by newName becomes the new name of the invoking File object.
• It will return true upon success and false if the file cannot be renamed
2) delete()
• It deletes the disk file represented by the path of the invoking File object
Syntax: boolean delete( )
• You can also use delete( ) to delete a directory if the directory is empty.
• delete( ) returns true if it deletes the file and false if the file cannot be removed.
void deleteOnExit( ) Removes the file associated with the invoking object when the JVM
terminates.
long getFreeSpace( ) Returns the number of free bytes of storage available on the partition
associated with the invoking object.
long getTotalSpace( ) Returns the storage capacity of the partition associated with the invoking
object. (Added by Java SE 6.)
long getUsableSpace( ) Returns the number of usable free bytes of storage available on the partition
associated with the invoking object. (Added by Java SE 6.)
isAbsolute( ) method returns true if the file has an absolute path and false if its path is relative.
File also includes two useful utility methods.
• This method closes the invoking stream, releasing any resources that it may hold.
• This interface is implemented by all of the I/O classes that open a stream that can be closed.
Objects of a class that implements Flushable can force buffered output to be written to the
stream to which the object is attached.
It defines the flush( ) method, shown here:
• Flushing a stream typically causes buffered output to be physically written to the underlying
device.
• This interface is implemented by all of the I/O classes that write to a stream.
• In general, you should use the character stream classes when working with characters or
strings, and use the byte stream classes when working with bytes or other binary objects.
1) InputStream:
• InputStream is an abstract class that defines Java’s model of streaming byte input.
• It implements the Closeable interface.
• Most of the methods in this class will throw an IOException on error conditions.
2) OutputStream:
Method Description
void close( ) Closes the output stream. Further write attempts will generate an
IOException
void flush( ) Finalizes the output state so that any buffers are cleared. That is, it flushes
the output buffers.
void write(int b) Writes a single byte to an output stream. Note that the parameter is an int,
which allows you to call write( ) with expressions without having to cast
them back to byte.
void write(byte buffer[ ]) Writes a complete array of bytes to an output stream.
void write(byte buffer[ ], Writes a subrange of numBytes bytes from the array buffer, beginning at
int offse int numBytes) buffer[offset].
4.2.5 FileInputStream
• The FileInputStream class creates an InputStream that you can use to read bytes from a file Its
two most common constructors are shown here:
FileInputStream(String filepath)
FileInputStream(File fileObj)
import java.io.*;
class FileInputStreamDemo {
public static void main(String args[]) throws IOException {
int size;
InputStream f =
new FileInputStream("FileInputStreamDemo.java");
System.out.println("Total Available Bytes: " + (size = f.available()));
int n = size/40;
System.out.println("First " + n +" bytes of the file one read() at a time");
for (int i=0; i < n; i++) {
System.out.print((char) f.read());
}
System.out.println("\nStill Available: " + f.available());
OUTPUT:
4.2.6 FileOutputStream
• FileOutputStream creates an OutputStream that you can use to write bytes to a file.
• Its most commonly used constructors are shown here:
FileOutputStream(String filePath)
FileOutputStream(File fileObj)
FileOutputStream(String filePath, boolean append)
FileOutputStream(File fileObj, boolean append)
// Demonstrate FileOutputStream.
import java.io.*;
class FileOutputStreamDemo {
public static void main(String args[]) throws IOException {
String source = "Now is the time for all good men\n" + " to come to the aid of their country\n" +
" and pay their due taxes.";
byte buf[] = source.getBytes();
OutputStream f0 = new FileOutputStream("file1.txt");
for (int i=0; i < buf.length; i += 2) {
f0.write(buf[i]);
}
f0.close();
OutputStream f1 = new FileOutputStream("file2.txt");
f1.write(buf);
f1.close();
OutputStream f2 = new FileOutputStream("file3.txt");
f2.write(buf,buf.length-buf.length/4,buf.length/4);
f2.close();
}}
4.2.7 Serialization
• Serialization is the process of writing the state of an object to a byte stream.
• This is useful when you want to save the state of your program to a persistent storage area,
such as a file.
• At a later time, you may restore these objects by using the process of deserialization.
• Serialization is also needed to implement Remote Method Invocation (RMI).
• RMI allows a Java object on one machine to invoke a method of a Java object on a different
machine.
• An object may be supplied as an argument to that remote method.
• The sending machine serializes the object and transmits it. The receiving machine deserializes
it.
Serializable
• object that implements the Serializable interface can be saved and restored by the serialization
facilities.
• The Serializable interface defines no members. It is simply used to indicate that a class may
be serialized.
• If a class is serializable, all of its subclasses are also serializable.
• Variables that are declared as transient are not saved by the serialization facilities. Also,
• static variables are not saved.
If a variable is declared as Transient
then its state (value) is not stored
during the Serialization process. (in a
simple way all normal variable values
are stored permanently during
Serialization, Except a Transient
variables value)
This program demonstrates that the instance variables of object1 and object2 are identical.
OUTPUT:
object1: s=Hello; i=-7; d=2.7E10
object2: s=Hello; i=-7; d=2.7E10
OUTPUT:
New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
One: 5
Two: 5
Three: 5
One: 4
Two: 4
Three: 4
One: 3
Three: 3
Two: 3
One: 2
Three: 2
Two: 2
One: 1
Three: 1
Two: 1
One exiting.
Two exiting.
Three exiting.
Main thread exiting.
join( ) :
– commonly use to wait for a thread to finish is called join( ), shown here:
final void join( ) throws InterruptedException
– This method waits until the thread on which it is called terminates.
– Ex: with join function main will wait until all the threads finish their exaction.
Thread Priority ranges from MIN_PRIORITY and MAX_PRIORITY level i.e. from 1 to 10,
Default priority, specify NORM_PRIORITY, which is currently 5
Calling thread priority method:
Syntax: ThreadName.setPriority(int Number);
Ex: A ThreadA = new A();
ThreadA.setPriority(Thread.Max_PRIORITY);
You can obtain the current priority setting by calling the getPriority( ) method of Thread, shown here:
final int getPriority( )
OUTPUT:
Start thread A
Start thread B
threadA started
End of main Thread
threadB started
from Thread A:i=1
from Thread B:j=1
from Thread A:i=2
from Thread B:j=2
from Thread B:j=3
from Thread B:j=4
Exit from B
from Thread A:i=3
from Thread A:i=4
Exit from A
4.8 SYNCHRONIZATION
• Because multithreading introduces an asynchronous behavior to your programs, there must be
a way for you to enforce synchronicity when you need it.
• For example, if you want two threads to communicate and share a common file or data
structure, you need some way to ensure that they don’t conflict with each other.
• That is, you must prevent one thread from writing data while another thread is in the middle
of reading it.
• Java uses monitor to achieve synchronization.
• You can think of a monitor as a very small box that can hold only one thread.
• Once a thread enters a monitor, all other threads must wait until that thread exits the monitor.
• In this way, a monitor can be used to protect a shared asset from being manipulated by more
than one thread at a time.
• Most multithreaded systems expose monitors as objects that your program must explicitly
acquire and manipulate.
• Java provides a cleaner solution. There is no class “Monitor”; instead, each object has
its own implicit monitor that is automatically entered when one of the object’s
synchronized methods is called.
• Once a thread is inside a synchronized method, no other thread can call any other
synchronized method on the same object.
All the calls to methods which are not synchronized should be kept in that. Then call to them
will be taken as synchronized.
• wait( ) tells the calling thread to give up the monitor and go to sleep until some other thread
enters the same monitor and calls notify( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of the
threads will be granted access.
wait() method:
• wait( ) normally waits until notify( ) or notifyAll( ) is called,
• But there may be situations where it may be wakened due to some unknown reason. So to
avoid this sun says always put wait in a loop which checks some condition on which the
thread is waiting.
Deadlock
• Occurs when two threads have a circular dependency on a pair of synchronized objects.
• For example, suppose one thread enters the monitor on object X and another thread enters the
monitor on object Y.
• If the thread in X tries to call any synchronized method on Y, it will block as expected.
However, if the thread in Y, in turn, tries to call any synchronized method on X, the thread
waits forever, because to access X, it would have to release its own lock on Y so that the first
thread could complete.
Deadlock
• Occurs when two threads have a circular dependency on a pair of synchronized objects.
• For example, suppose one thread enters the monitor on object X and another thread enters the
monitor on object Y.
• If the thread in X tries to call any synchronized method on Y, it will block as expected.
However, if the thread in Y, in turn, tries to call any synchronized method on X, the thread
waits forever, because to access X, it would have to release its own lock on Y so that the first
thread could complete.