Java - Programming Module4 (Multithreading& Collections)
Java - Programming Module4 (Multithreading& Collections)
Multithreading
Multithreading in java is a process of executing multiple threads simultaneously.
A thread is a lightweight sub-process, the smallest unit of processing. Multiprocessing and
multithreading, both are used to achieve multitasking.
However, we use multithreading than multiprocessing because threads use a shared memory
area. They don't allocate separate memory area so saves memory, and context-switching between
the threads takes less time than process.
Advantages of Java Multithreading
1) It doesn't block the user because threads are independent and you can perform multiple
operations at the same time.
2) You can perform many operations together, so it saves time.
3) Threads are independent, so it doesn't affect other threads if an exception occurs in a single
thread.
16) void destroy() It is used to destroy the thread group and all of
its subgroups.
21) static interrupted() It tests whether the current thread has been
boolean interrupted.
24) static holdLock() It returns true if and only if the current thread
boolean holds the monitor lock on the specified object.
31) void notify() It is used to give the notification for only one
thread which is waiting for a particular object.
4.2
}
public static void main(String args[]){
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
}
Output:running thread name is:Thread-0
running thread priority is:10
running thread name is:Thread-1
running thread priority is:1
t1.start();//starting threads
t2.start();
t3.start();
}
}
}
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output: 5
100
10
200
15
300
20
400
25
500
synchronized method
If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object
and releases it when the thread completes its task.
//example of java synchronized method
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
}
}
t1.start();
t2.start();
}
}
Output: 5
10
15
20
25
100
200
300
400
500
Method Description
publicfinalvoidwait()throwsInterruptedException waitsuntilobjectisnotified.
publicfinalvoidwait(longtimeout)throwsInterruptedEx waitsforthespecifiedamountoft
ception ime.
The current thread must own this object's monitor, so it must be called from the synchronized
method only otherwise it will throw exception.
Method Description
public final void wait()throws InterruptedException waits until object is notified.
public final void wait(long timeout)throws waits for the specified amount
InterruptedException of time.
2) notify() method
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on
this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the
discretion of the implementation. Syntax:
public final void notify()
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor. Syntax:
public final void notifyAll()
Understanding the process of inter-thread communication
Why wait(), notify() and notifyAll() methods are defined in Object class not Thread class?
It is because they are related to lock and object has a lock.
Difference between wait and sleep?
Let's see the important differences between wait and sleep methods.
wait() sleep()
wait() method releases the lock sleep() method doesn't release the lock.
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}.start();
}}
Output: going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
13 public <T> T[] toArray(T[] a) It converts collection into array. Here, the
runtime type of the returned array is that
of the specified array.
Collection Interface
The Collection interface is the interface which is implemented by all the classes in the collection
framework. It declares the methods that every collection will have. In other words, we can say
that the Collection interface builds the foundation on which the collection framework depends.
Some of the methods of Collection interface are Boolean add ( Object obj), Boolean addAll (
Collection c), void clear(), etc. which are implemented by all the subclasses of Collection
interface.
List Interface
List interface is the child interface of Collection interface. It inhibits a list type data structure in
which we can store the ordered collection of objects. It can have duplicate values.
List interface is implemented by the classes ArrayList, LinkedList, Vector, and Stack.
To instantiate the List interface, we must use :
1. List <data-type> list1= new ArrayList();
2. List <data-type> list2 = new LinkedList();
3. List <data-type> list3 = new Vector();
4. List <data-type> list4 = new Stack();
There are various methods in List interface that can be used to insert, delete, and access the
elements from the list.
The classes that implement the List interface are given below.
4.8 Collection Classes
ArrayList
The ArrayList class implements the List interface. It uses a dynamic array to store the duplicate
element of different data types. The ArrayList class maintains the insertion order and is non-
synchronized. The elements stored in the ArrayList class can be randomly accessed. Consider the
following example.
import java.util.*;
class TestJavaCollection1{
public static void main(String args[]){
ArrayList<String> list=new ArrayList<String>();//Creating arraylist
list.add("Ravi");//Adding object in arraylist
list.add("Vijay");
list.add("Ravi");
list.add("Ajay");
//Traversing list through Iterator
Iterator itr=list.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ravi
Vijay
Ravi
Ajay
LinkedList
LinkedList implements the Collection interface. It uses a doubly linked list internally to store the
elements. It can store the duplicate elements. It maintains the insertion order and is not
synchronized. In LinkedList, the manipulation is fast because no shifting is required.
Consider the following example.
import java.util.*;
public class TestJavaCollection2{
public static void main(String args[]){
LinkedList<String> al=new LinkedList<String>();
al.add("Ravi");
al.add("Vijay");
al.add("Ravi");
al.add("Ajay");
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ravi
Vijay
Ravi
Ajay
Vector
Vector uses a dynamic array to store the data elements. It is similar to ArrayList. However, It is
synchronized and contains many methods that are not the part of Collection framework.
Consider the following example.
import java.util.*;
public class TestJavaCollection3{
public static void main(String args[]){
Vector<String> v=new Vector<String>();
v.add("Ayush");
v.add("Amit");
v.add("Ashish");
v.add("Garima");
Iterator<String> itr=v.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ayush
Amit
Ashish
Garima
Stack
The stack is the subclass of Vector. It implements the last-in-first-out data structure, i.e., Stack.
The stack contains all of the methods of Vector class and also provides its methods like boolean
push(), boolean peek(), boolean push(object o), which defines its properties.
Consider the following example.
import java.util.*;
public class TestJavaCollection4{
public static void main(String args[]){
Stack<String> stack = new Stack<String>();
stack.push("Ayush");
stack.push("Garvit");
stack.push("Amit");
stack.push("Ashish");
stack.push("Garima");
stack.pop();
Iterator<String> itr=stack.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ayush
Garvit
Amit
Ashish
Queue Interface
Queue interface maintains the first-in-first-out order. It can be defined as an ordered list that is
used to hold the elements which are about to be processed. There are various classes like
PriorityQueue, Deque, and ArrayDeque which implements the Queue interface.
Queue interface can be instantiated as:
1. Queue<String> q1 = new PriorityQueue();
2. Queue<String> q2 = new ArrayDeque();
There are various classes that implement the Queue interface, some of them are given below.
PriorityQueue
The PriorityQueue class implements the Queue interface. It holds the elements or objects which
are to be processed by their priorities. PriorityQueue doesn't allow null values to be stored in the
queue.
Consider the following example.
import java.util.*;
public class TestJavaCollection5{
public static void main(String args[]){
PriorityQueue<String> queue=new PriorityQueue<String>();
queue.add("Amit Sharma");
queue.add("Vijay Raj");
queue.add("JaiShankar");
queue.add("Raj");
System.out.println("head:"+queue.element());
System.out.println("head:"+queue.peek());
System.out.println("iterating the queue elements:");
Iterator itr=queue.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
queue.remove();
queue.poll();
System.out.println("after removing two elements:");
Iterator<String> itr2=queue.iterator();
while(itr2.hasNext()){
System.out.println(itr2.next());
}
}
}
Output:
head:Amit Sharma
head:Amit Sharma
iterating the queue elements:
Amit Sharma
Raj
JaiShankar
Vijay Raj
after removing two elements:
Raj
Vijay Raj
Deque Interface
Deque interface extends the Queue interface. In Deque, we can remove and add the elements
from both the side. Deque stands for a double-ended queue which enables us to perform the
operations at both the ends.
Deque can be instantiated as:
1. Deque d = new ArrayDeque();
ArrayDeque
ArrayDeque class implements the Deque interface. It facilitates us to use the Deque. Unlike
queue, we can add or delete the elements from both the ends.
ArrayDeque is faster than ArrayList and Stack and has no capacity restrictions.
Consider the following example.
import java.util.*;
public class TestJavaCollection6{
public static void main(String[] args) {
//Creating Deque and adding elements
Deque<String> deque = new ArrayDeque<String>();
deque.add("Gautam");
deque.add("Karan");
deque.add("Ajay");
//Traversing elements
for (String str : deque) {
System.out.println(str);
}
}
}
Output:
Gautam
Karan
Ajay
Set Interface
Set Interface in Java is present in java.util package. It extends the Collection interface. It
represents the unordered set of elements which doesn't allow us to store the duplicate items. We
can store at most one null value in Set. Set is implemented by HashSet, LinkedHashSet, and
TreeSet.
Set can be instantiated as:
1. Set<data-type> s1 = new HashSet<data-type>();
2. Set<data-type> s2 = new LinkedHashSet<data-type>();
3. Set<data-type> s3 = new TreeSet<data-type>();
HashSet
HashSet class implements Set Interface. It represents the collection that uses a hash table for
storage. Hashing is used to store the elements in the HashSet. It contains unique items.
Consider the following example.
import java.util.*;
public class TestJavaCollection7{
public static void main(String args[]){
//Creating HashSet and adding elements
HashSet<String> set=new HashSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Ravi");
set.add("Ajay");
//Traversing elements
Iterator<String> itr=set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Vijay
Ravi
Ajay
LinkedHashSet
LinkedHashSet class represents the LinkedList implementation of Set Interface. It extends the
HashSet class and implements Set interface. Like HashSet, It also contains unique elements. It
maintains the insertion order and permits null elements.
Consider the following example.
import java.util.*;
public class TestJavaCollection8{
public static void main(String args[]){
LinkedHashSet<String> set=new LinkedHashSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Ravi");
set.add("Ajay");
Iterator<String> itr=set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ravi
Vijay
Ajay
SortedSet Interface
SortedSet is the alternate of Set interface that provides a total ordering on its elements. The
elements of the SortedSet are arranged in the increasing (ascending) order. The SortedSet
provides the additional methods that inhibit the natural ordering of the elements.
The SortedSet can be instantiated as:
SortedSet<data-type> set = new TreeSet();
TreeSet
Java TreeSet class implements the Set interface that uses a tree for storage. Like HashSet,
TreeSet also contains unique elements. However, the access and retrieval time of TreeSet is quite
fast. The elements in TreeSet stored in ascending order.
Consider the following example:
import java.util.*;
public class TestJavaCollection9{
public static void main(String args[]){
//Creating and adding elements
TreeSet<String> set=new TreeSet<String>();
set.add("Ravi");
set.add("Vijay");
set.add("Ravi");
set.add("Ajay");
//traversing elements
Iterator<String> itr=set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
Output:
Ajay
Ravi
Vijay
4.9 Iterator interface
Iterator interface provides the facility of iterating the elements in a forward direction only.
Methods of Iterator interface
There are only three methods in the Iterator interface. They are:
No. Method Description
1 public boolean It returns true if the iterator has more elements otherwise
hasNext() it returns false.
2 public Object next() It returns the element and moves the cursor pointer to
the next element.
3 public void remove() It removes the last elements returned by the iterator. It is
less used.
Iterable Interface
The Iterable interface is the root interface for all the collection classes. The Collection interface
extends the Iterable interface and therefore all the subclasses of Collection interface also
implement the Iterable interface.
It contains only one abstract method. i.e.,
1. Iterator<T> iterator()
It returns the iterator over the elements of type T.
.