OOC Module 4
OOC Module 4
SEMESTER – IV
MODULE - 4
Prepared by,
Mrs. Shammi.L
MODULE 4
PACKAGES AND INTERFACES
The following concepts should be learn in this Module
Packages, Access Protection, Importing Packages, Interfaces. Multi - Threaded Programming: Multi-
Threaded Programming: What are threads? How to make the classes threadable ; Extending threads;
Implementing runnable; Synchronization; Changing state of the thread; Bounded buffer problems,
producer consumer problems.
Text book 2: CH: 9 Ch 11: RBT: L1, L2, L3
1. PACKAGES:
package pkg;
Java uses file system directories to store packages. For example, the .class files for any classes
you declare to be part of MyPackage must be stored in a directory called MyPackage.
package pkg1[.pkg2[.pkg3]];
• Reusability: Reusability of code is one of the most important requirements in the software
industry. Reusability saves time, effort and also ensures consistency. A class once developed
can be reused by any number of programs wishing to incorporate the class in that particular
program.
• Easy to locate the files.
•In real life situation there may arise scenarios where we need to define files of the same
name. This may lead to ―name-space collisions‖. Packages are a way of avoiding ―name-
space collisions‖.
Package are categorized into two forms
• Built-in Package:-Existing Java package for example java.lang, java.util etc.
1. import package.*;
2. import package.classname;
3. fully qualified name.
1) Using packagename.*
If you use package.* then all the classes and interfaces of this package will be accessible but not
sub packages. The import keyword is used to make the classes and interface of another package
accessible to the current package.
//save by A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.*;
2) Using packagename.classname
If you import package.classname then only declared class of this package will be accessible.
//save by A.java
4TH Sem, Dept. of CSE, EPCET 4 Prepared by: Mrs. Shammi.L
MODULE 4: PACKAGES AND INTERFACES` OOC-18CS45
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
//save by B.java
package mypack;
import pack.A;
class B{
public static void main(String args[]){
A obj = new A();
obj.msg();
}
}
//save by B.java
package mypack;
class B{
public static void main(String args[]){
Access Specifiers
• private: accessible only in the class
• default : so-called ―package‖ access — accessible only in the same package
• protected: accessible (inherited) by subclasses, and accessible by code in same package
• public: accessible anywhere the class is accessible, and inherited by subclasses
2.1 Thread:
➢ A thread is a lightweight sub process, a smallest unit of processing.
➢ It is a separate path of execution.
➢ Threads are independent, if there occurs exception in one thread, it doesn't
affect other threads.
➢ It shares a common memory area.
2.2 Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use multitasking to
utilize the CPU. Multitasking can be achieved by two ways:
➢ Process-based Multitasking(Multiprocessing)
➢ Thread-based Multitasking(Multithreading)
• Each process have its own address in memory i.e. each process allocates separate
memory area.
• Process is heavyweight.
• Cost of communication between the processes is high.
• Switching from one process to another require some time for saving and loading
registers, memory maps, updating lists etc.
• Less efficient
• Threads share the same address space and therefore can share both data and code.
An instance of Thread class is just an object, like any other object in java. But a thread of execution
means an individual "lightweight" process that has its own call stack. In java each thread has its
own call stack
When a Java program starts up, one thread begins running immediately. This is usually called the
main thread of your program, because it is the one that is executed when your program begins.
The main thread is important for two reasons:
• It is the thread from which other ―child‖ threads will be spawned.
• Often, it must be the last thread to finish execution because it performs various shutdown actions.
The life cycle of the thread in java is controlled by JVM. The java thread states are as follows:
1. New
2. Runnable
3. Running
4. Non-Runnable (Blocked)
5. Terminated
1) New
The thread is in new state if you create an instance of Thread class but before the invocation of
start() method.
2) Runnable
When we call start() function on Thread object, it’s state is changed to Runnable. The control is
given to Thread scheduler to finish it’s execution. Whether to run this thread instantly or keep it
in runnable thread pool before running, depends on the OS implementation of thread scheduler.
3) Running
When thread is executing, it’s state is changed to Running. Thread scheduler picks one of the
thread from the runnable thread pool and change its state to Running. Then CPU starts executing
this thread. A thread can change state to Runnable, Dead or Blocked from running state depends
on time slicing, thread completion of run() method or waiting for some resources.
4) Non-Runnable (Blocked)
This is the state when the thread is still alive, but is currently not eligible to run. Waiting −
Sometimes, a thread transitions to the waiting state while the thread waits for another thread to
perform a task. A thread transitions back to the runnable state, only when another thread signals
the waiting thread to continue its execution.
5) Terminated
When the thread starts it schedules the time slots for several sub threads and the JVM scheduler
schedules the time slot to every thread based on round robin technique or priority based.
Method Description
Signature
String getName() Retrieves the name of running thread in the current context in String format
void start() This method will start a new thread of execution by calling run() method of
Thread/runnable object.
void run() This method is the entry point of the thread. Execution of thread starts from
this method.
void sleep(int This method suspend the thread for mentioned time duration in argument
sleeptime) (sleeptime in ms)
void yield() By invoking this method the current thread pause its execution temporarily
and allow other threads to execute.
void join() This method used to queue up a thread in execution. Once called on thread,
current thread will wait till calling thread completes its execution
Creates a thread by a new class that extends Thread class. This creates an instance of that class.
The extending class must override run() method which is the entry point of new thread.
System.out.println("thread is running...");
t1.start();
thread is running
The easiest way to create a thread is to create a class that implements the runnable interface. After
implementing runnable interface, the class needs to implement the run() method, which is of form,
public void run()
• run() method introduces a concurrent thread into your program. This thread will end when
run() returns.
• You must specify the code for your thread inside run() method.
• run() method can call other methods, can use other classes and declare variables just like any
other normal method.
After you create a class that implements Runnable, you will instantiate an object of type Thread
from within that class. Thread defines several constructors. The one that we will use is shown
here:
Syntax :
Thread(Runnable threadOb, String threadName);
In this constructor, threadOb is an instance of a class that implements the Runnable interface. This
defines where execution of the thread will begin. The name of the new thread is specified by
threadName.
{
System.out.println("concurrent thread started running..");
}
class MyThreadDemo
{
public static void main( String args[] )
{
MyThread mt = new MyThread();
Thread t = new Thread(mt);
t.start();
}
package applet1;
import java.io.*;
import java.util.*;
class A implements Runnable {
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println(i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println( "Interrupted");
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
System.out.println(" exiting.");
}
}
class multithread {
public static void main(String args[]) {
A obj1 = new A();
B obj2= new B();
Thread t1=new Thread(obj1);
Thread t2=new Thread(obj2);
t1.start();
t2.start();
}}
1
exiting.
exiting.
Notice the call to sleep(10000) in main( ). This causes threads B and A to sleep for ten seconds
and ensures that it will finish last.
Note : Write a java application program for generating 3 threads to perform the
following operations.
In java, isAlive() and join() are two different methods to check whether a thread has finished its
execution.
The isAlive() method returns true if the thread upon which it is called is still running otherwise it
returns false.
t1.start();
t2.start();
Output :
r1
true
true
r1
r2
r2
But, join() method is used more commonly than isAlive(). This method waits until the thread on
which it is called terminates
Using join() method, we tell our thread to wait until the specified thread completes its execution.
There are overloaded versions of join() method, which allows us to specify time for which you
want to wait for the specified thread to terminate.
}
public static void main(String[] args)
{
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.start();
try{
}catch(InterruptedException ie){}
t2.start();
}
}
r1
r2
r1
r2
In this above program join() method on thread t1 ensures that t1 finishes it process before thread
t2 starts.
t1.join(1500);
2.5 Synchronization
At times when more than one thread try to access a shared resource, we need to ensure that
resource will be used by only one thread at a time. The process by which this is achieved is called
synchronization. The synchronization keyword in java creates a block of code referred to as
critical section.
Key to synchronization is the concept of the monitor. A monitor is an object that is used
as a mutually exclusive lock. Only one thread can own a monitor at a given time. When a thread
acquires a lock, it is said to have entered the monitor. All other threads attempting to enter the
locked monitor will be suspended until the first thread exits the monitor. These other threads are
said to be waiting for the monitor.
1. Mutual Exclusive
1. Synchronized method.
2. Synchronized block.
3. static synchronization.
Synchronized block can be used to perform synchronization on any specific resource of the
method. Synchronized block is used to lock an object for any shared resource. Scope of
synchronized block is smaller than the method.
General Syntax :
synchronized (object)
//statement to be synchronized
class Table{
void display(int n)
{
synchronized(this)
{
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
try{
Thread.sleep(400);
}
catch(Exception e){
System.out.println(e);
}
Table t;
A(Table t)
{
this.t=t;
}
public void run(){
t.display(5);
}
}
class B extends Thread{
Table t;
B(Table t)
{
this.t=t;
}
public void run(){
t.display(100);
A t1=new A(obj);
B t2=new B(obj);
t1.start();
t2.start();
}
}
5
10
15
20
25
100
200
300
400
500
class Table{
A(Table t)
{
this.t=t;
}
}
class B extends Thread{
Table t;
B(Table t){
this.t=t;
}
t2.start();
}
}
5
10
15
20
25
100
200
300
400
• The producer’s job is to generate data, put it into the buffer, and start again.
• At the same time, the consumer is consuming the data (i.e. removing it from the
buffer), one piece at a time.
This problem can be implemented or solved by different ways in Java, classical way is using wait
and notify method to communicate between Producer and Consumer thread and blocking each of them on
individual condition like full queue and empty queue.
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( ) or notifyAll( ).
notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of the threads
will be granted access.
c1.start();
}
}
4TH Sem, Dept. of CSE, EPCET 27 Prepared by: Mrs. Shammi.L
MODULE 4. PACKAGES AND INTERFACES` OOC-18CS45
class Myclass {
private int contents;
private boolean available = false;
}
}
class Consumer extends Thread {
this.number = number;
}
public void run() {
int value = 0;
}
public void run() {
for (int i = 0; i < 10; i++) {
Myclass.put(i);
} catch (InterruptedException e) { }
}
}}
Producer #1 put: 0
Consumer #1 got: 0
Producer #1 put: 1
Consumer #1 got: 1
Producer #1 put: 2
Consumer #1 got: 2
Producer #1 put: 3
Consumer #1 got: 3
Producer #1 put: 4
Consumer #1 got: 4
Producer #1 put: 5
Consumer #1 got: 5
Producer #1 put: 6
Consumer #1 got: 6
Producer #1 put: 7
Consumer #1 got: 7
Producer #1 put: 8
Consumer #1 got: 8
Producer #1 put: 9
Consumer #1 got: 9
Bounded buffer problem, which is also called producer consumer problem, is one of the classic
problems of synchronization.
Problem Statement:
There is a buffer of n slots and each slot is capable of storing one unit of data. There are two
processes running, namely, producer and consumer, which are operating on the buffer.
A producer tries to insert data into an empty slot of the buffer. A consumer tries to remove data
from a filled slot in the buffer. As you might have guessed by now, those two processes won’t
produce the expected output if they are being executed concurrently.
There needs to be a way to make the producer and consumer work in an independent manner.
import java.io.*;
import java.util.*;
class Buffer
{
}
public synchronized void insert(int ch)
{
try
{
while (BufferSize == MaxBuffSize) {
wait();
}
BufferEnd = (BufferEnd + 1) % MaxBuffSize;
}
}
public synchronized int delete() {
int ch=0;
try {
while (BufferSize == 0) {
wait();
}
ch = store[BufferStart];
BufferStart = (BufferStart + 1) % MaxBuffSize;
BufferSize--;
notifyAll();
} catch (InterruptedException e) {
return ch;
}
}
public Producer(Buffer b) {
buffer = b;
}
public void run() {
for(int c=0;c<10;c++)
buffer.insert(c);
}
}
} catch (InterruptedException e) {}
System.out.println("End of Program");
}
}
0
1
2
3
4
5
6
End of Program
Readers writer problem is another example of a classic synchronization problem. There are many
variants of this problem, one of which is examined below.
Problem Statement:
There is a shared resource which should be accessed by multiple processes. There are two types
of processes in this context. They are reader and writer. Any number of readers can read from
the shared resource simultaneously, but only one writer can write to the shared resource. When a
writer is writing data to the resource, no other process can access the resource. A writer cannot
write to the resource if there are non-zero number of readers accessing the resource.
Solution:
From the above problem statement, it is evident that readers have higher priority than writer. If a
writer wants to write to the resource, it must wait until there are no readers currently accessing that
resource.
5. Deadlock
A special type of error that you need to avoid that relates specifically to multitasking is deadlock, which
occurs when two threads have a circular dependency on a pair of synchronized objects. Deadlock is a
difficult error to debug for two reasons:
• In general, it occurs only rarely, when the two threads time-slice in just the right way.
• It may involve more than two threads and two synchronized objects.
class A
{
synchronized void foo(B b)
{
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try
{
Thread.sleep(1000);
}
catch(Exception e)
4TH Sem, Dept. of CSE, EPCET 36 Prepared by: Mrs. Shammi.L
MODULE 4. PACKAGES AND INTERFACES` OOC-18CS45
{
System.out.println("A Interrupted");
}
System.out.println(name + "trying to call B.last()");
b.last();
}
synchronized void last()
{
System.out.println("Inside A.last");
}
class B
{
synchronized void bar(A a)
{
String name = Thread.currentThread().getName();
System.out.println(name + "entered B.bar");
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println("B Interrupted");
}
System.out.println(name + "trying to call A.last()");
a.last();
}
synchronized void last()
{
System.out.println("Inside A.last");
}
}
Deadlock()
Output:
Because the program has deadlocked, you need to press CTRL-C to end the program. You can see a full
thread and monitor cache dump by pressing CTRL-BREAK on a PC.
Prior to Java 2 , a program used suspend() and resume(), which are methods defined by Thread, to pause and
restart the execution of a thread. They have the form shown below:
The Thread class also defines a method called stop() that stops a thread. Its signature is shown here:
The NewThread class contains a Boolean instance variable named suspendFlag, which is used to control the
execution of the thread. It is initialized to false by the constructor. The run() method contains a synchronized
stqtement block that checks suspendflag. Idf that variable is true, the wait() method is invoked to suspend the
execution of the thread. The mysuspend() method sets suspendFlag to true. The myresume() method sets
suspendFlag to false and invokes notify() to wake up the thread. Finally, the main() method has been modified
to invoke the mysuspend() and myresume() methods.
7. Using multithreading:
The key to utilizing java’s multithreading features effectively is to think concurrently rather than serially.
For example, when you have two subsystems within a program that can execute concurrently, make them
individual threads.