0% found this document useful (0 votes)
5 views27 pages

Unit IV Notes Java

The document provides an overview of multithreaded programming, explaining the concepts of threads and multitasking, as well as the differences between process-based and thread-based multitasking. It details how to create threads in Java using the Thread class and Runnable interface, along with methods for managing thread execution and priorities. Additionally, it discusses synchronization in multithreading and introduces the legacy Vector class for managing dynamic arrays.

Uploaded by

318Giri Prasad C
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views27 pages

Unit IV Notes Java

The document provides an overview of multithreaded programming, explaining the concepts of threads and multitasking, as well as the differences between process-based and thread-based multitasking. It details how to create threads in Java using the Thread class and Runnable interface, along with methods for managing thread execution and priorities. Additionally, it discusses synchronization in multithreading and introduces the legacy Vector class for managing dynamic arrays.

Uploaded by

318Giri Prasad C
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Unit-IV

Overview of Multithreaded Programming

A multithreaded program contains two or more parts that can run concurrently. Each part of such a
program is called a thread, and each thread defines a separate path of execution. Thus,
multithreading is a specialized form of multitasking.

There are two distinct types of multitasking:

I. Process-based
II. Thread-based.

It is important to understand the difference between the two. For most readers, process-based
multitasking is the more familiar form. A process is, in essence, a program that is executing. Thus,
process-based multitasking is the feature that allows your computer to run two or more programs
concurrently. For example, process-based multitasking enables you to run the Java compiler at the
same time that you are using a text editor. In process-based multitasking, a program is the smallest
unit of code that can be dispatched by the scheduler.

In a thread-based multitasking environment, the thread is the smallest unit of dispatchable code.
This means that a single program can perform two or more tasks simultaneously. For instance, a
text editor can format text at the same time that it is printing, as long as these two actions are being
performed by two separate threads. Thus, process-based multitasking deals with the "big picture,"
and thread-based multitasking handles the details.

Multitasking threads require less overhead than multitasking processes. Processes are heavyweight
tasks that require their own separate address spaces. Interprocess communication is expensive and
limited. Context switching from one process to another is also costly. Threads, on the other hand,
are lightweight. They share the same address space.

Introduction to Java Thread model

Threads exist in several states. A thread can be running. It can be ready to run as soon as it gets
CPU time. A running thread can be suspended, which temporarily suspends its activity. A
1|Page
suspended thread can then be resumed, allowing it to pick up where it left off. A thread can be
blocked when waiting for a resource. At any time, a thread can be terminated, which halts its
execution immediately. Once terminated, a thread cannot be resumed.

Creating threads

There are two ways to create a thread:


1. By extending Thread class
2. By implementing Runnable interface.
Thread class:
Thread class provide constructors and methods to create and perform operations on a
thread.Thread class extends Object class and implements Runnable interface.
Commonly used Constructors of Thread class:
o Thread()
o Thread(String name)
o Thread(Runnable r)
o Thread(Runnable r,String name)
Commonly used methods of Thread class:
1. public void run(): is used to perform action for a thread.
2. public void start(): starts the execution of the thread.JVM calls the run() method on the
thread.

2|Page
3. public void sleep(long miliseconds): Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.
4. public void join(): waits for a thread to die.
5. public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
10. public Thread currentThread(): returns the reference of currently executing thread.
11. public int getId(): returns the id of the thread.
12. public Thread.State getState(): returns the state of the thread.
13. public boolean isAlive(): tests if the thread is alive.
14. public void yield(): causes the currently executing thread object to temporarily pause and
allow other threads to execute.
15. public void suspend(): is used to suspend the thread(depricated).
16. public void resume(): is used to resume the suspended thread(depricated).
17. public void stop(): is used to stop the thread(depricated).
18. public boolean isDaemon(): tests if the thread is a daemon thread.
19. public void setDaemon(boolean b): marks the thread as daemon or user thread.
20. public void interrupt(): interrupts the thread.
21. public boolean isInterrupted(): tests if the thread has been interrupted.
22. public static boolean interrupted(): tests if the current thread has been interrupted.
Runnable interface:
The Runnable interface should be implemented by any class whose instances are intended to be
executed by a thread. Runnable interface have only one method named run().
1. public void run(): is used to perform action for a thread.
Starting a thread:
The start() method of Thread class is used to start a newly created thread. It performs the
following tasks:
o A new thread starts(with new callstack).
o The thread moves from New state to the Runnable state.
o When the thread gets a chance to execute, its target run() method will run.

1) Java Thread Example by extending Thread class

3|Page
FileName: Multi.java
class Multi extends Thread{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}
Output:
thread is running...

2) Java Thread Example by implementing Runnable interface

FileName: Multi3.java
class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
}

public static void main(String args[]){


Multi3 m1=new Multi3();
Thread t1 =new Thread(m1); // Using the constructor Thread(Runnable r)
t1.start();
}
}
Output:
thread is running...

Creating multiple threads


While implementing Runnable interface or extending Thread class, you have to
override run() method.
4|Page
Example : Code for creating multiple thread.
public class B extends Thread {

public void run() {


System.out.println();
for (int i = 1; i <= 5; i++) {
System.out.println(" Thread name = "+ Thread.currentThread().getName());
}
}
public static void main(String[] args) {
B t1 = new B();
t1.start();

B t2 = new B();
t2.start();

B t3 = new B();
t3.start();
}
Output : When you compile and execute the program the output will be as below

Assigning Thread priorities


The setPriority() method of thread class is used to change the thread's priority. Every thread has a
priority which is represented by the integer number between 1 to 10.
Thread class provides 3 constant properties:
1. public static int MIN_PRIORITY: It is the maximum priority of a thread. The value of it is 1.
2. public static int NORM_PRIORITY: It is the normal priority of a thread. The value of it is 5.
3. public static int MAX_PRIORITY: It is the minimum priority of a thread. The value of it is 10.

We can also set the priority of thread between 1 to 10. This priority is known as custom priority or
user defined priority.

5|Page
Syntax
1. public final void setPriority(int a)

Parameter
a: It is the priority to set this thread to.

Return
It does not return any value.

Exception
IllegalArgumentException: This exception throws if the priority is not in the range
MIN_PRIORITY to MAX_PRIORITY.
SecurityException: This exception throws if the current thread cannot modify this thread.

Maximum Priority Thread

public class JavaSetPriorityExp1 extends Thread


{
public void run()
{
System.out.println("Priority of thread is: "+Thread.currentThread().getPriority());
}
public static void main(String args[])
{
// creating one thread
JavaSetPriorityExp1 t1=new JavaSetPriorityExp1();
// print the maximum priority of this thread
t1.setPriority(Thread.MAX_PRIORITY);
// call the run() method
t1.start();
}
}
Output:

6|Page
Priority of thread is: 10

Minimum Priority Thread

public class JavaSetPriorityExp2 extends Thread


{
public void run()
{
System.out.println("Priority of thread is: "+Thread.currentThread().getPriority());
}
public static void main(String args[])
{
// creating one thread
JavaSetPriorityExp2 t1=new JavaSetPriorityExp2();
// print the minimum priority of this thread
t1.setPriority(Thread.MIN_PRIORITY);
// This will call the run() method
t1.start();
}
}
Output:
Priority of thread is: 1

Normal Priority Thread

public class JavaSetPriorityExp3 extends Thread


{
public void run()
{
System.out.println("Priority of thread is: "+Thread.currentThread().getPriority());
}
public static void main(String args[])
{
// creating one thread

7|Page
JavaSetPriorityExp3 t1=new JavaSetPriorityExp3();
// print the normal priority of this thread
t1.setPriority(Thread.NORM_PRIORITY);
// starting the thread
t1.start();
}
}
Output:
Priority of thread is: 5

User define Priority Thread

public class JavaSetPriorityExp4 extends Thread


{
public void run()
{
System.out.println("running...");
}
public static void main(String args[])
{
// creating one thread
JavaSetPriorityExp4 t1=new JavaSetPriorityExp4();
JavaSetPriorityExp4 t2=new JavaSetPriorityExp4();
// set the priority
t1.setPriority(4);
t2.setPriority(7);
// print the user defined priority
System.out.println("Priority of thread t1 is: " + t1.getPriority()); //4
System.out.println("Priority of thread t2 is: " + t2.getPriority()); //7
// this will call the run() method
t1.start();
}
}
Output:

8|Page
Priority of thread t1 is: 4
Priority of thread t2 is: 7
running...

When priority is greater than 10

public class JavaSetPriorityExp5 extends Thread


{
public void run()
{
System.out.println("running...");
}
public static void main(String args[])
{
// creating one thread
JavaSetPriorityExp5 t1=new JavaSetPriorityExp5();
JavaSetPriorityExp5 t2=new JavaSetPriorityExp5();
// set the priority
t1.setPriority(12);
t2.setPriority(7);
// print exception because priority of t1 is greater than 10
System.out.println("Priority of thread t1 is: " + t1.getPriority());
System.out.println("Priority of thread t2 is: " + t2.getPriority());
// call the run() method
t1.start();
}
}
Output:
Exception in thread "main" java.lang.IllegalArgumentException
at java.lang.Thread.setPriority(Thread.java:1089)
at JavaSetPriorityExp5.main(JavaSetPriorityExp5.java:13)

Applying Synchronization

9|Page
Java programming language provides a very handy way of creating threads and synchronizing their
task by using synchronized blocks. You keep shared resources within this block. Following is the
general form of the synchronized statement −
Syntax
synchronized(objectidentifier)
{
// Access shared variables and other shared resources
}
Here, the objectidentifier is a reference to an object whose lock associates with the monitor that
the synchronized statement represents. Now we are going to see two examples, where we will print
a counter using two different threads. When threads are not synchronized, they print counter value
which is not in sequence, but when we print counter by putting inside synchronized() block, then it
prints counter very much in sequence for both the threads.

Multithreading Example without Synchronization

Here is a simple example which may or may not print counter value in sequence and every time we
run it, it produces a different result based on CPU availability to a thread.

Example

class PrintDemo {
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}

class ThreadDemo extends Thread {

10 | P a g e
private Thread t;
private String threadName;
PrintDemo PD;

ThreadDemo( String name, PrintDemo pd) {


threadName = name;
PD = pd;
}

public void run() {


PD.printCount();
System.out.println("Thread " + threadName + " exiting.");
}

public void start () {


System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}

public class TestThread {


public static void main(String args[]) {

PrintDemo PD = new PrintDemo();

ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );


ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );

T1.start();
T2.start();

11 | P a g e
// wait for threads to end
try {
T1.join();
T2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
This produces a different result every time you run this program −
Output
Starting Thread - 1
Starting Thread - 2
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 5
Counter --- 2
Counter --- 1
Counter --- 4
Thread Thread - 1 exiting.
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 2 exiting.

Multithreading Example with Synchronization

Here is the same example which prints counter value in sequence and every time we run it, it
produces the same result.

Example

class PrintDemo {

12 | P a g e
public void printCount() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}

class ThreadDemo extends Thread {


private Thread t;
private String threadName;
PrintDemo PD;

ThreadDemo( String name, PrintDemo pd) {


threadName = name;
PD = pd;
}

public void run() {


synchronized(PD) {
PD.printCount();
}
System.out.println("Thread " + threadName + " exiting.");
}

public void start () {


System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}

13 | P a g e
}
}

public class TestThread {

public static void main(String args[]) {


PrintDemo PD = new PrintDemo();

ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );


ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );

T1.start();
T2.start();

// wait for threads to end


try {
T1.join();
T2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
This produces the same result every time you run this program −
Output
Starting Thread - 1
Starting Thread - 2
Counter --- 5
Counter --- 4
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 1 exiting.
Counter --- 5

14 | P a g e
Counter --- 4
Counter --- 3
Counter --- 2
Counter --- 1
Thread Thread - 2 exiting.

Introduction to Legacy Classes


Working with Vector class

Vector implements a dynamic array. It is similar to ArrayList, but with two differences: Vector is
synchronized, and it contains many legacy methods that are not part of the collections framework.
With the release of Java 2, Vector was reengineered to extend AbstractList and implement the
List interface, so it now is fully compatible with collections.

Here are the Vector constructors:

Vector( )
Vector(int size)
Vector(int size, int incr)
Vector(Collection c)

Some of the Methods

final void addElement(Object element) : The object specified by element is added to the vector.

final int capacity( ) : Returns the capacity of the vector.

final int size( ) : Returns the number of elements currently in t he vector.

final Object firstElement( ) : Returns the first element in the vector.

final Enumeration elements( ) : Returns an enumeration of the elements in the vector.

Examples using Vector class


import java.util.*;
class VectorDemo {
public static void main(String args[]) {
// initial size is 3, increment is 2
Vector v = new Vector(3, 2);
System.out.println("Initial size: " + v.size());
15 | P a g e
System.out.println("Initial capacity: " + v.capacity());
v.addElement(new Integer(1));
v.addElement(new Integer(2));
v.addElement(new Integer(3));
v.addElement(new Integer(4));
System.out.println("Capacity after four additions: " + v.capacity());
v.addElement(new Double(5.45));
System.out.println("Current capacity: " + v.capacity());
v.addElement(new Double(6.08));
v.addElement(new Integer(7));
System.out.println("Current capacity: " + v.capacity());
v.addElement(new Float(9.4));
v.addElement(new Integer(10));
System.out.println("Current capacity: " + v.capacity());
v.addElement(new Integer(11));
v.addElement(new Integer(12));
System.out.println("First element: " + (Integer)v.firstElement());
System.out.println("Last element: " +
(Integer)v.lastElement());
if(v.contains(new Integer(3)))
System.out.println("Vector contains 3.");
// enumerate the elements in the vector.
Enumeration vEnum = v.elements();
System.out.println("\\nElements in vector:");
while(vEnum.hasMoreElements())
System.out.print(vEnum.nextElement() + " ");
System.out.println();
}
}

output

Initial size: 0
Initial capacity: 3

16 | P a g e
Capacity after four additions: 5
Current capacity: 5
Current capacity: 7
Current capacity: 9
First element: 1
Last element: 12
Vector contains 3.

Elements in vector:
1 2 3 4 5.45 6.08 7 9.4 10 11 12

Understanding Stack class

Stack is a subclass of Vector that implements a standard last-in, first-out stack. Stack only defines the
default constructor, which creates an empty stack. Stack includes all the methods defined by Vector, and
adds several of its own

Methods

Examples using Stack class

import java.util.*;
class StackDemo {
static void showpush(Stack st, int a) {
st.push(new Integer(a));
System.out.println("push(" + a + ")");

17 | P a g e
System.out.println("stack: " + st);
}
static void showpop(Stack st) {
System.out.print("pop -> ");
Integer a = (Integer) st.pop();
System.out.println(a);
System.out.println("stack: " + st);
}
public static void main(String args[]) {
Stack st = new Stack();
System.out.println("stack: " + st);
showpush(st, 42);
showpush(st, 66);
showpush(st, 99);
showpop(st);
showpop(st);
showpop(st);
try {
showpop(st);
} catch (EmptyStackException e) {
System.out.println("empty stack");
}
}
}

Output

stack: [ ]
push(42)
stack: [42]
push(66)
stack: [42, 66]
push(99)
stack: [42, 66, 99]

18 | P a g e
pop -> 99
stack: [42, 66]
pop -> 66
stack: [42]
pop -> 42
stack: [ ]
pop -> empty stack

Introduction to Legacy Interfaces

Instead, it defined several classes and an interface that provided an ad hoc method of storing
objects. With the addition of collections by Java 2, several of the original classes were
reengineered to support the collection interfaces. Thus, they are fully compatible with the
framework. While no classes have actually been deprecated, one has been rendered obsolete. Of
course, where a collection duplicates the functionality of a legacy class, you will usually want to
use the collection for new code. In general, the legacy classes are supported because a large base of
code exists that uses them, including code still used by the Java 2 API.One other point: None of
the collection classes are synchronized, but all the legacy classes are synchronized. This distinction
may be important in some situations. Of course, you can easily synchronize collections, too, by
using one of the algorithms provided by Collections.

The legacy classes defined by java.util are shown here:

Dictionary
Hashtable
Properties
Stack
Vector

There is one legacy interface called Enumeration. The following sections examine
Enumeration and each of the legacy classes, in turn.

Understanding Enumeration Interface

19 | P a g e
The Enumeration interface defines the methods by which you can enumerate (obtain one at a
time) the elements in a collection of objects. This legacy interface has been superceded by
Iterator. Although not deprecated, Enumeration is considered obsolete for new code. However, it
is used by several methods defined by the legacy classes (such as Vector and Properties), is used
by several other API classes, and is currently in widespread use in application code.

Enumeration specifies the following two methods:

boolean hasMoreElements( )
Object nextElement( )

When implemented, hasMoreElements( ) must return true while there are still more elements to
extract, and false when all the elements have been enumerated. nextElement( ) returns the next
object in the enumeration as a generic Object reference. That is, each call to nextElement( )
obtains the next object in the enumeration.

Introduction to Utility classes


Working with StringTokenizer
The processing of text often consists of parsing a formatted input string. Parsing is the
division of text into a set of discrete parts, or tokens, which in a certain sequence can
convey a semantic meaning. The StringTokenizer class provides the first step in this
parsing process, often called the lexer (lexical analyzer) or scanner. StringTokenizer
implements the Enumeration interface. Therefore, given an input string, you can
enumerate the individual tokens contained in it using StringTokenizer.
To use StringTokenizer, you specify an input string and a string that contains delimiters.
Delimiters are characters that separate tokens. Each character in the delimiters string is
considered a valid delimiter—for example, ",;:" sets the delimiters to a comma,
semicolon, and colon. The default set of delimiters consists of the whitespace characters:
space, tab, newline, and carriage return.

The StringTokenizer constructors are shown here:

StringTokenizer(String str)
20 | P a g e
StringTokenizer(String str, String delimiters)
StringTokenizer(String str, String delimiters, boolean delimAsToken)

In all versions, str is the string that will be tokenized. In the first version, the default
delimiters are used. In the second and third versions, delimiters is a string that specifies
the delimiters. In the third version, if delimAsToken is true, then the delimiters are also
returned as tokens when the string is parsed. Otherwise, the delimiters are not returned.
Delimiters are not returned as tokens by the first two forms.
Working with Date class

The Date class encapsulates the current date and time. Before beginning our
examination of Date, it is important to point out that it has changed substantially from its
original version defined by Java 1.0. When Java 1.1 was released, many of the functions
carried out by the original Date class were moved into the Calendar and DateFormat
classes, and as a result, many of the original 1.0 Date methods were deprecated. Java 2
adds a few new methods to the time and date classes,

Date supports the following constructors:


Date( )
Date(long millisec)

Example

import java.util.Date;
class DateDemo {
public static void main(String args[]) {
// Instantiate a Date object
Date date = new Date();
// display time and date using toString()
System.out.println(date);
// Display number of milliseconds since midnight, January 1, 1970 GMT
long msec = date.getTime();
System.out.println("Milliseconds since Jan. 1, 1970 GMT = " + msec);
}
21 | P a g e
}

Sample output is shown here:

Mon Jan 25 15:06:40 CST 1999


Milliseconds since Jan. 1, 1970 GMT = 917298400228

Working with Calendar

The abstract Calendar class provides a set of methods that allows you to convert a time
in milliseconds to a number of useful components. Some examples of the type of
information that can be provided are: year, month, day, hour, minute, and second. It is
intended that subclasses of Calendar will provide the specific functionality to interpret
time information according to their own rules. This is one aspect of the Java class library
that enables you to write programs that can operate in several international
environments. An example of such a subclass is GregorianCalendar.

Calendar provides no public constructors.

Some commonly used methods defined by Calendar

22 | P a g e
23 | P a g e
Example

import java.util.Calendar;
class CalendarDemo {
public static void main(String args[]) {
String months[] = {
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"};
// Create a calendar initialized with the
// current date and time in the default
// locale and timezone.
Calendar calendar = Calendar.getInstance();
// Display current time and date information.

24 | P a g e
System.out.print("Date: ");
System.out.print(months[calendar.get(Calendar.MONTH)]);
System.out.print(" " + calendar.get(Calendar.DATE) + " ");
System.out.println(calendar.get(Calendar.YEAR));
System.out.print("Time: ");
System.out.print(calendar.get(Calendar.HOUR) + ":");
System.out.print(calendar.get(Calendar.MINUTE) + ":");
System.out.println(calendar.get(Calendar.SECOND));
// Set the time and date information and display it.
calendar.set(Calendar.HOUR, 10);
calendar.set(Calendar.MINUTE, 29);
calendar.set(Calendar.SECOND, 22);
System.out.print("Updated time: ");
System.out.print(calendar.get(Calendar.HOUR) + ":");
System.out.print(calendar.get(Calendar.MINUTE) + ":");
System.out.println(calendar.get(Calendar.SECOND));
}
}
Sample output is shown here:
Date: Jan 25 1999
Time: 11:24:25
Updated time: 10:29:22

Working with Random Class


The Random class is a generator of pseudorandom numbers. These are called
pseudorandom numbers because they are simply uniformly distributed sequences.
Random defines the following constructors:
Random( )
Random(long seed)
The first version creates a number generator that uses the current time as the starting, or
seed, value. The second form allows you to specify a seed value manually.

25 | P a g e
Example

import java.util.Random;
class RandDemo {
public static void main(String args[]) {
Random r = new Random();
double val;
double sum = 0;
int bell[] = new int[10];
for(int i=0; i<100; i++) {
val = r.nextGaussian();
sum += val;
double t = -2;
for(int x=0; x<10; x++, t += 0.5)
if(val < t) {
bell[x]++;
break;

26 | P a g e
}
}
System.out.println("Average of values: " +
(sum/100));
// display bell curve, sideways
for(int i=0; i<10; i++) {
for(int x=bell[i]; x>0; x—)
System.out.print("*");
System.out.println();
}
}
}
Here is a sample program run. As you can see, a bell-like distribution of numbers is
obtained.
Average of values: 0.0702235271133344
**
*******
******
***************
******************
*****************
*************
**********
********
***
Working with Scanner Class

27 | P a g e

You might also like