Module - 5 merged
Module - 5 merged
DEPARTMENTOFCOMPUTERSCIENCEANDENGINEERING(CSE)
Module-5
MultithreadedProgramming
MultithreadinginJavaallowsforconcurrentexecutionofmultiplepartsofaprogram,knownas threads.
Thiscontrastswithprocess-basedmultitasking,whereeachprogramisaseparateunit,whereas threads share
the same address space and belong to the same process.
Multithreadingisadvantageousduetoitsloweroverheadcomparedtoprocess-basedmultitasking.
It helps in maximizing processing power by minimizing idle time, especially in interactive and
networked environments where tasks like data transmission and user input are slower compared to
CPU processing speed.
Multithreading enables more efficient use of available resources and smoother program execution by
allowing other threads to run while one is waiting.
TheJavaThreadModel
Java'sruntimesystemheavily reliesonthreadstoenableasynchronousbehavior,whichhelpsin
utilizing CPU cycles more efficiently.
Unlikesingle-threadedsystemsthatuseeventloopswithpolling,Java'smultithreadingeliminatesthe need
for such mechanisms. In single-threaded environments, blocking one thread can halt the entire
program, leading to inefficiencies and potential domination of one part over others.
WithJava'smultithreading,onethreadcanpausewithoutaffectingotherpartsoftheprogram,
allowing idle time to be utilized elsewhere.
Thisisparticularlybeneficialfortaskslikeanimationloops,wherepausesbetweenframesdon'thalt the
entire system. Multithreading in Java works seamlessly on both single-core and multicore systems,
with threads sharing CPU time on single-core systems and potentially executing simultaneously on
multicore systems.
ThreadsinJavacanexistinvariousstates,includingrunning,readytorun,suspended,blocked,or
terminated. Each state represents a different stage ofthread execution, with the abilityto suspend,
resume, or terminate threads as needed.
Overall,Java'smultithreadingcapabilitiescontributetomoreefficientandresponsivesoftware
development.
ThreadPriorities
:Javaassignseachthreadaprioritytodetermineitsrelativeimportance.Higher-priority
ThreadPriorities threads are given preference during contex
Thread States:Threadscanbeinvariousstateslikerunning,readytorun,suspended,blocked,orterminated. These states govern th
Synchronization: Javaprovidesmechanismslikemonitorstoenforcesynchronicitybetweenthreads,ensuring that shared resourc
Messaging:Javafacilitatescommunicationbetweenthreadsthroughpredefinedmethodsthatallobjectshave. This messaging syst
: Java's multithreading system is built around theclassand created either by extending theclass or implementing the
tswithamainthread,whichisautomaticallycreated.Themainthread is crucial for spawning other threads and often performs shu
ThreadClassandRunnableInterface Thread
the Runnable interface.Threadscanbe Thread
Runnable interface.
MainThread :EveryJavaprogramstar
CreatingaThread
ImplementingRunnableInterface:Tocreateathread,youimplementtheRunnableinterfaceinaclass.This interface
abstracts a unit of executable code and requires implementing a single method called run().
InstantiatingThreadObject:AfterimplementingRunnable,youinstantiateanobjectoftypeThreadwithinthat class.
The Thread constructor requires an instance of a class that implements Runnable and a name for the thread.
classNewThreadimplementsRunnable{ Thread
t;
NewThread(){
//Createanew,secondthread
t = new Thread(this, "Demo Thread");
System.out.println("Childthread:"+t);
}
//Entrypointforthesecondthread public
void run() {
try{
for(int i = 5; i > 0; i--)
{ System.out.println("ChildThread:"+i);
Thread.sleep(500);
}
} catch (InterruptedException e)
{ System.out.println("Childinterrupted."
);
}
System.out.println("Exitingchildthread.");
}
}
classThreadDemo{
publicstaticvoidmain(String[]args){
NewThreadnt=newNewThread();//createanewthread
nt.t.start(); // Start the thread
//Mainthreadcontinuesitsexecution
//...
}
}
ExtendingThread
Example:
classNewThreadextendsThread{ Ne
wThread() {
//InvokeThreadconstructortosetthreadname
super("Demo Thread");
System.out.println("Child thread: " + this);
}
//Entrypointforthesecondthread
public void run() {
try{
for(int i = 5; i > 0; i--)
{ System.out.println("ChildThread:"+i);
Thread.sleep(500);
}
} catch (InterruptedException e)
{ System.out.println("Childinterrupted."
);
}
System.out.println("Exitingchildthread.");
}
}
classExtendThread{
publicstaticvoidmain(String[]args){
NewThreadnt=newNewThread();//createanewthread nt.start(); //
start the thread
//Mainthreadcontinuesitsexecution
//...
}
}
CreatingMultipleThreads
classNewThreadimplements
Runnable{Stringname;//
name of thread Thread t;
NewThread(String
threadname){name=
threadname;
t = new Thread(this, name);
System.out.println("Newthread:"+t);
}
//Thisistheentrypointforthread.
public void run() {
try{
for(int i = 5; i > 0; i--)
{ System.out.println(name+":"+i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name+"Interrupted");
}
System.out.println(name+ "exiting.");
}
}
classMultiThreadDemo{
publicstatic void main(String[]args){NewThread
nt1=newNewThread("One");NewThreadnt2=
new NewThread("Two"); NewThread nt3=new
NewThread("Three");
//Startthethreads.nt1.t.start();
nt2.t.start();
nt3.t.start();
try{
//waitforotherthreadstoend Thread.sleep(10000);
}catch(InterruptedExceptione){System.out.println("Main
threadInterrupted");
}
System.out.println("Mainthreadexiting.");
}
}
Sampleoutputfromthisprogramisshownhere.(Youroutputmayvarybasedupon
thespecificexecutionenvironment.)
UsingisAlive()andjoin()
Usingthe isAlive() and join() methodsinJavathreads:
isAlive()Method:
DefinedbytheThread class.
Returns trueifthethreaduponwhichitiscalledisstillrunning.
Returnsfalseotherwise.
Occasionallyusefulforcheckingthestatusofathread.
join()Method:
AlsodefinedbytheThreadclass.
Waitsuntilthethreadonwhichitiscalled terminates.
Thecallingthreadwaitsuntilthespecifiedthreadjoinsit.
Additionalformsof join()allowspecifyingamaximumamountoftimetowaitforthespecifiedthreadto
terminate.
Usage:
join() iscommonlyusedtoensurethatonethreadwaitsforanotherthreadtofinishitsexecution.
Thisisparticularlyusefulwhenyouwantthemainthreadtofinishlastor whenyouneedtosynchronizethe execution
of multiple threads.
Example:
Animprovedversionoftheexamplecodecanusejoin()toensurethatthemainthreadisthelasttostop.
Additionally,isAlive()canbeusedtocheckifathreadisstillrunning.
//Usingjoin()towaitforthreadstofinish.class
NewThread implements Runnable {
Stringname;//nameofthread
Thread t;
NewThread(Stringthreadname){
name = threadname;
t=newThread(this,name);System.out.println("New
thread: " + t);
}
//Thisistheentrypointforthread.public void
run() {
try{
for(inti=5;i>0;i--){System.out.println(name+": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name+ "exiting.");
}
classDemoJoin{
publicstatic void main(String[]args){NewThread
nt1=newNewThread("One");NewThreadnt2=
new NewThread("Two"); NewThread nt3=new
NewThread("Three");
//Startthethreads.nt1.t.start();
nt2.t.start();
nt3.t.start();
System.out.println("ThreadOneisalive:"
+nt1.t.isAlive());System.out.println("Thread
Two is alive:
+nt2.t.isAlive());System.out.println("Thread
"Threeisalive:"
+nt3.t.isAlive());
//waitforthreadstofinishtry{
System.out.println("Waiting for threads to finish."); nt1.t.join();
nt2.t.join();
nt3.t.join();
}catch(InterruptedExceptione){System.out.println("Main
threadInterrupted");
}
System.out.println("ThreadOneisalive:"
+nt1.t.isAlive());System.out.println("Thread
Two is alive:
+nt2.t.isAlive());System.out.println("Thread
"Threeisalive:"
+nt3.t.isAlive());
System.out.println("Mainthreadexiting.");
}
ThreadPriorities
ThreadPriorities :
Threadprioritiesareusedbythethreadschedulertodecidewheneachthreadshouldbeallowedtorun.
Intheory,higher-prioritythreadsgetmoreCPUtimethanlower-prioritythreadsoveragivenperiodoftime.
Higher-prioritythreadscanpreemptlower-priorityones, meaningtheycaninterrupttheexecutionoflower-
priority threads.
EqualPriorityThreads:
Intheory,threadsofequalpriorityshouldgetequalaccesstotheCPU.
However,Javaisdesignedtoworkinvariousenvironments,andtheactualbehavior maydifferdepending on the
operating system and multitasking implementation.
Toensurefairness,threadsthatsharethesamepriorityshouldyieldcontroloccasionally,especiallyin
nonpreemptive environments.
SettingThreadPriority:
UsethesetPriority()methodtosetathread'spriority.
Syntax:voidsetPriority(intlevel)
The level parameterspecifiesthenewprioritysettingforthethread,anditmustbewithintherange of
MIN_PRIORITY and MAX_PRIORITY,currently1and10,respectively.
Toreturnathreadtodefaultpriority,useNORM_PRIORITY,whichiscurrently5.
GettingThreadPriority:
Usethe getPriority()methodtoobtainthecurrentprioritysettingofathread.
Syntax:intgetPriority()
ImplementationConsiderations:
ImplementationsofJavamayhavedifferentbehaviorswhenitcomestoschedulingandthreadpriorities.
Toensurepredictableandcross-platformbehavior,it'sadvisabletousethreadsthatvoluntarilygiveupCPU time.
Synchronization
When two or more threads need access to a shared resource, they need some way to
ensurethattheresource willbeusedbyonlyonethreadatatime.Theprocessbywhich this is
achieved is called synchronization.
Key to synchronization is the concept of the monitor. A monitor is an object that is
used as a mutually exclusive lock.
Onlyonethreadcanownamonitoratagiventime.Whenathreadacquiresalock,it is said to have
entered the monitor. All other threads attempting to enter the locked monitorwill
besuspended until thefirst thread exits themonitor.These other threads are said to
bewaiting for themonitor.A thread that ownsa monitor can reenter the same monitor if it
so desires.
Youcansynchronizeyourcodeineitheroftwoways.Bothinvolvetheuseofthe
synchronizedkeyword,andbothareexaminedhere.
UsingSynchronized Methods
ImplicitMonitors
:
AllobjectsinJavahavetheirownimplicitmonitorassociatedwiththem.
Toenteranobject'smonitor,youcancallamethodthathasbeenmodifiedwith the synchronized keyword.
Whileathreadisinsidea synchronized methodofanobject,allotherthreadsthattrytocallsynchronized
methodsonthesameinstancehaveto wait.
:
NeedforSynchronization
Synchronizationisnecessarytoensurethreadsafety,especiallywhenmultiplethreadsaccessshared resources concurrent
Withoutsynchronization,concurrentaccesstosharedresourcescanleadtodatacorruption,raceconditions, and other inco
Example:
Theexampleprogramconsistsofthreeclasses: Callme , Caller ,and Synch .
The Callme classhasa method call() whichprintsamessageinsidesquarebracketsandthenpausesthe
threadforonesecondusingThread.sleep(1000).
The calls Caller
The classtakesareferencetoaninstanceof methodCallme
which
andamessagestring.Itcreatesanewthread
in turn calls the that
the run()
classcreatesasingleinstanceof call() methodon theinstance.
Callme
Synch Callme and three instances of,eachwithaunique
Caller instance.
Caller
messagestring.Allinstancessharethe same Callme
//Thisprogramisnotsynchronized.class
Callme {
void call(String msg)
{ System.out.print("["+msg);tr
y
{
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
classCallerimplementsRunnable{String
msg;
Callme
target;
Threadt;
publicCaller(Callmetarg,Strings){target= targ;
msg= s;
t=newThread(this);
}
publicvoidrun(){target.call(msg);
}
}
classSynch{
publicstaticvoidmain(String[]args){Callme
target = new Callme();
Callerob1=newCaller(target,"Hello");
Callerob2=newCaller(target,"Synchronized");Caller ob3
= new Caller(target, "World");
//Startthethreads. ob1.t.start();
ob2.t.start();
ob3.t.start();
//waitforthreadstoendtry{
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
Hereistheoutputproduced bythisprogram:
[Hello[Synchronized[World]
]
]
InterthreadCommunication
Interprocesscommunicationusing wait(), notify(),and notifyAll() methodsinJava:
Purpose:
Thesemethodsprovideameansforthreadstocommunicateandcoordinatetheiractivitieswithoutusing polling,
which can waste CPU cycles.
MethodDefinitions:
wait():Tellsthecallingthreadtogiveupthemonitorandgotosleepuntilsomeotherthreadentersthe same
monitorandcalls notify() ornotifyAll().
notify() :Wakesupasinglethreadthatpreviouslycalled wait() onthesameobject.
notifyAll():Wakesupallthreadsthatpreviouslycalled wait() onthesameobject.Oneofthethreadswill be
granted access.
Allthreemethodsaredeclaredwithinthe Object classandcanonlybecalled fromwithinasynchronized
context.
AdditionalFormsofwait():
Additionalformsofthewait()methodexistthatallowyoutospecifyaperiodoftimetowait.
SpuriousWakeups:
Inrarecases,awaitingthreadcouldbeawakenedduetoaspuriouswakeup,wherewait()resumeswithout
notify() or notifyAll() beingcalled.Tohandlethis,callsto wait() areoftenplacedwithinaloopthatchecks
theconditiononwhichthethreadiswaiting.
Best Practices:
TheJavaAPIdocumentationrecommendsusingalooptocheckconditionswhenwaiting,especiallydueto the
possibility of spurious wakeups.
//Anincorrectimplementationofaproducerandconsumer.
classQ{ int
n;
synchronizedvoidput(intn){this.n
=n;System.out.println("Put:"+ n);
}
}
classProducerimplementsRunnable{
Q q;
Thread t;
Producer(Qq)
{this.q=q;
t=newThread(this,"Producer");
}
publicvoidrun(){ int
i = 0;
while(true){ q.put(i+
+);
}
}
}
classConsumerimplementsRunnable{
Q q;
Threadt;
Consumer(Qq){
this.q = q;
t=newThread(this,"Consumer");
}
publicvoidrun(){
while(true){
q.get();
}
}
}
classPC{
publicstaticvoidmain(String[]args){Qq=
new Q();
Producerp=newProducer(q);
Consumer c = new
Consumer(q);
//Startthethreads. p.t.start();
c.t.start();
System.out.println("PressControl-Ctostop.");
}
}
Although the put( ) and get( ) methods on Q are synchronized, nothing stops the
producer from overrunning the consumer, nor will anything stop the consumer from
consumingthesamequeuevaluetwice.Thus,yougettheerroneousoutputshownhere (the
exact output will vary with processor speed and task load):
Put: 1
Got: 1
Got: 1
Got: 1
Got: 1
Got: 1
Put: 2
Put: 3
Put: 4
Put: 5
Put: 6
Put: 7
Got: 7
//Acorrectimplementationofaproducerandconsumer.classQ
{
intn;
booleanvalueSet=false;
synchronizedintget(){ while(!valueSet)
try{
wait();
}catch(InterruptedExceptione){System.out.println("InterruptedException
caught");
}
System.out.println("Got:"+n);
valueSet = false;
notif
y();
retur
nn;
}
synchronizedvoidput(intn){
while(valueSet)
try{
wait();
}catch(InterruptedExceptione){System.out.println("InterruptedException caught");
}
this.n = n;
valueSet=true;
System.out.println("Put:"+n);
notify();
}
}
classProducerimplementsRunnable{
Q q;
Thread t;
Producer(Qq)
{this.q=q;
t=newThread(this,"Producer");
}
publicvoidrun(){ int
i = 0;
while(true){
q.put(i++);
}
}
}
classConsumerimplementsRunnable{
Q q;
Threadt;
Consumer(Qq){
this.q = q;
t=newThread(this,"Consumer");
}
publicvoidrun(){
while(true) {
q.get();
}
}
}
classPCFixed{
publicstaticvoidmain(String[]args){Qq=
new Q();
Producerp=newProducer(q);
Consumer c = new
Consumer(q);
//Startthethreads. p.t.start();
c.t.start();
System.out.println("PressControl-Ctostop.");
}
}
Inside get( ), wait( ) is called. This causes its execution to suspend until Producer
notifiesyouthatsomedataisready.Whenthishappens,executioninside get()resumes.
Afterthedata hasbeenobtained, get()callsnotify().ThistellsProducerthatitisokay to put
more data inthe queue. Inside put( ), wait( ) suspends executionuntil Consumer has
removed the item fromthe queue. When execution resumes, the next item of data is put
in the queue, and notify( ) is called. This tells Consumer that it should nowremove it.
Hereissomeoutputfromthisprogram,whichshowsthecleansynchronousbehavior:
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
Suspending,Resuming,andStoppingThreads
DeprecatedMethods:
InearlyversionsofJava(priortoJava2),threadsuspension,resumption,andterminationweremanaged
using suspend(),resume(),and methodsdefinedbythe
stop() class.
Thread
However,thesemethodsweredeprecatedduetopotentialissuesandriskstheyposed,suchascausing system
failures and leaving critical data structures in corrupted states.
ReasonsforDeprecation:
suspend(): Cancauseserioussystemfailures,asitdoesn'treleaselocksoncriticaldata structures,
potentially leading to deadlock.
resume():Deprecatedasitrequires suspend() toworkproperly.
stop():Cancausesystemfailuresbyleavingcriticaldatastructuresincorruptedstates.
AlternativeApproach:
Insteadofusingdeprecated methods,threadsshouldbedesignedtoperiodicallycheckaflagvariableto
determine whether to suspend, resume, or stop their own execution.
Typically,abooleanflagvariableisusedtoindicatetheexecutionstateofthethread.
Iftheflagissetto"running,"thethreadcontinuestoexecute.Ifit'ssetto"suspend,"thethreadpauses.Ifit's set to
"stop," the thread terminates.
ExampleUsingwait()andnotify():
The wait() andnotify()methodsinheritedfrom Objectcanbeusedtocontroltheexecutionofathread.
Anexampleprovideddemonstrateshowtousethesemethodstocontrolthreadexecution.
Itinvolvesabooleanflag( suspendFlag )tocontroltheexecutionofthethread.
The run() methodperiodicallychecks suspendFlag,andifit's true,thethread waits.Methods and mysuspend()
myresume() are used to set and unset the flag and notify the thread to wake up.
//Suspendingandresumingathreadthemodernway.class
NewThread implements Runnable {
Stringname;//nameofthread
Thread t;
boolean suspendFlag;
NewThread(Stringthreadname){
name=threadname;
t = new Thread(this, name);
System.out.println("Newthread:"+t);
suspendFlag = false;
}
//Thisistheentrypointforthread.
public void run() {
try{
for(int i = 15; i > 0; i--)
{ System.out.println(name + ": " + i);
Thread.sleep(200);synchronized(this) {
while(suspendFlag)
{ wait();
}
}
}
}catch(InterruptedExceptione){System.out.println(name+
"interrupted.");
}
System.out.println(name+ "exiting.");
}
synchronizedvoidmysuspend(){ suspendFlag
= true;
}
synchronizedvoidmyresume(){
suspendFlag=false;notify();
}
}
classSuspendResume{
publicstaticvoidmain(String[]args){NewThread
ob1=newNewThread("One");NewThreadob2
=newNewThread("Two");
ob1.t.start();//Startthethreadob2.t.start();//Start
thethread
try{
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("SuspendingthreadOne"); Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming threadOne");
ob2.mysuspend();
System.out.println("SuspendingthreadTwo");Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming threadTwo");
} catch (InterruptedException e) {
System.out.println("MainthreadInterrupted");
}
//waitforthreadstofinishtry{
System.out.println("Waiting for threads to finish."); ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("MainthreadInterrupted");
}
System.out.println("Mainthreadexiting.");
}
}
Whenyouruntheprogram,youwillseethethreadssuspendandresume.Laterinthisbook,
you will see more examples that use the modern mechanism of thread control. Although this
mechanismmaynotappearassimpletouseastheoldway,nevertheless,itisthewayrequiredto ensure that
run-time errors don’t occur. It is the approach that mustbe used for all new code.
ObtainingaThread’sState
WecanobtainthecurrentstateofathreadbycallingthegetState()methoddefinedby
Thread. It is shown here:
Thread.StategetState()
Itreturnsavalueoftype Thread.Statethatindicatesthestateofthethreadatthetime at which
the call was made. State is an enumeration defined by Thread. (An enumeration is a
list of named constants. It is discussed in detail in Chapter 12.) Here are the values that
can be returned by getState( ):
Value State
BLOCKED Athreadthathassuspendedexecutionbecauseitiswaitingtoacquirea lock.
Thread.Statets=thrd.getState();if(ts==
Thread.State.RUNNABLE) // ...
Itisimportantto understandthatathread’sstatemaychangeafterthecalltogetState().
Thus,dependingonthecircumstances,thestateobtainedbycalling getState() maynotreflecttheactual state of
the thread only a moment later. For this (and other) reasons, getState( ) is not intended toprovide a
means of synchronizing threads. It’s primarily used for debugging or for profiling a thread’s run-time
characteristics.
Module-5
Enumerations
Enumerations in Java provide a structured way to define a new data type with named
constants representing legal values.
They offer a more robust alternative to using final variables for defining constant
values. Enumerations are commonly used to represent sets of related items, such as
error codes or states of a device.
In Java, enumerations are implemented as classes, allowing for constructors,
methods, and instance variables, which greatly enhances their capabilities and
flexibility.
TheyareextensivelyusedthroughouttheJavaAPIlibraryduetotheirpowerand versatility.
EnumerationFundamentals
1. Definition
:
Enumerationsarecreatedusingthe
enum keyword.
Constantswithintheenumerationarecalledenumeration constants.
:
2. ConstantsDeclaration
Enumeration constants are implicitly declared as public, static, final members oft
Eachconstant isofthetypeofthe enumerationin whichitis declared.
3. Instantiation
:
Enumerationsdefineaclasstype,buttheyarenotinstantiatedusingthe new
keyword.
Enumerationvariablesaredeclaredandusedsimilarlytoprimitivetypes.
4. AssignmentandComparison:
Enumerationvariablescanonlyholdvaluesdefinedbythe enumeration.
Constantscanbeassignedtoenumerationvariablesusingthedotnotation
(EnumType.Constant).
Constantscanbecomparedforequalityusingt == relationaloperator.
he
5. SwitchStatements:
Enumerationvaluescanbeusedtocontrolswitch statements.
All case statements within the switch must use constants from the
same enum as the switch expression.
Constantsincasestatementsarereferencedwithoutqualificationbytheir
enumeration type name.
6. DisplayingEnumerationConstants:
Enumerationconstantsaredisplayedbyoutputtingtheir names.
Enumeration constants are referenced using the dot notation
(EnumType.Constant)
Thefollowingprogramputstogetherallofthepiecesanddemonstratesthe
Appleenumeration:
classEnumDemo{
publicstaticvoidmain(String[]args)
{
Appleap;
ap=Apple.RedDel;
//Outputanenumvalue.System.out.println("Valueofap:"+ap);
System.out.println();
ap=Apple.GoldenDel;
//Comparetwoenumvalues.if(ap==
Apple.GoldenDel)
System.out.println("apcontainsGoldenDel.\n");
//Useanenumtocontrolaswitchstatement.switch(ap){
caseJonathan:System.out.println("Jonathanisred.");break;
caseGoldenDel:
System.out.println("Golden Delicious is yellow."); break;
caseRedDel:
System.out.println("RedDeliciousisred.");break;
caseWinesap:System.out.println("Winesapisred.");break;
caseCortland:System.out.println("Cortlandisred.");break;
}
}
}
Theoutputfromtheprogramisshownhere:
Valueofap:RedDel
Deliciousisyellow.
Thevalues()andvalueOf()Methods
Allenumerationsautomaticallycontaintwopredefinedmethods:values()and
valueOf().
Theirgeneralformsareshownhere:
publicstaticenum-type[]values()
publicstatic enum-typevalueOf(Stringstr)
The values( ) method returns an array that contains a list of the enumeration
constants.
The valueOf( ) method returns the enumeration constant whose value
correspondstothestringpassedinstr.Inbothcases,enum-typeisthetypeof the
enumeration.
For example, in the case of the Apple enumeration shown earlier, the return
type of Apple.valueOf("Winesap") is Winesap.
Thefollowingprogramdemonstratesthevalues()andvalueOf()methods:
//Usethebuilt-inenumerationmethods.
classEnumDemo2{
public staticvoidmain(String[]args)
{
Appleap;
System.out.println("HereareallAppleconstants:");
//usevalues()
Apple[]allapples=Apple.values();
for(Apple a : allapples)
System.out.println(a);
System.out.println();
//usevalueOf()
ap = Apple.valueOf("Winesap"); System.out.println("ap
contains " + ap);
}
}
Theoutputfromtheprogramisshownhere:
HereareallAppleconstants:
Jonat
han
Golde
nDel
RedD
el
Wine
sap
Cortl
and
apcontainsWinesap
Notice that this program uses a for-each style for loop to cycle through the array of constants obtained by
calling values( ). For the sake of illustration, the variable allapples wascreatedandassignedareference to
theenumerationarray.However,thisstepisnot necessarybecausetheforcouldhavebeenwrittenasshown here,
eliminating the need for the allapples variable:
for(Apple a : Apple.values())
System.out.println(a);
Now,noticehowthevaluecorrespondingtothenameWinesapwasobtainedbycallingvalueOf().
ap=Apple.valueOf("Winesap");
JavaEnumerationsAreClassTypes
1. EnumasClassType
:
Javaenumerationsaretreatedasclasstypes.
Theyhavesimilarcapabilitiesasotherclasses,allowingconstructors,instance variable
2. EnumerationConstants
:
Eachenumerationconstantisanobjectofitsenumeration type.
Constructorscanbedefinedforenums,andtheyarecalledwhenea
ch enumeration constant is created.
Instancevariablesdefinedwithintheenumareassociatedwitheachenumer
ation constant separately.
3. ExamplewithAppleEnum:
Anexampleisprovidedwitha
Apple enumrepresentingdifferentvarietiesof
n apples.
Eachconstanthasanassociatedpricestoredinaninstancevariable.
A Apple(intp)
constructor initializesthepriceforeachapplevariety.
returns the price of the apple variety.
A methodgetPrice()
4. UsageExample:
method,thepricesofdifferentapplevarietiesare displayed.
Inthe main()
Theconstructoriscalledforeachenumerationconstanttoinitializetheprices.
Instancemethodscanbecalledonenumerationconstantstoretrieveassoci
ated data.
5. OverloadedConstructors:
Enumerationscanhavetwoormoreoverloadedconstructors,justlikeo
ther classes.
Anexampleisprovidedwithadefaultconstructorinitializingthepriceto -
1when no price data is available.
//Useanenumconstructor.enumApple{
Jonathan(10), GoldenDel(9), RedDel, Winesap(15), Cortland(8); private int price; // price of each apple
//Constructor
Apple(intp){price=p;}
//OverloadedconstructorApple(){price
=-1; }
intgetPrice(){returnprice;}
}
EnumerationsInheritEnum
1. Inheritance:
AllJavaenumerationsautomaticallyinheritfromthe java.lang.Enum class.
Whileyoucan'tinheritasuperclasswhendeclaringanenu
java.lang.Enum is
m, implicitly inherited by all enums.
2. java.lang.EnumMethods:
ordinal()Method:
Returnstheordinalvalueoftheinvokingenumerationconstant.
Ordinalvaluesstartatzeroandincrease sequentially.
Example:Apple.Jonathan.ordinal()wouldreturn0.
compareTo()Method:
Comparestheordinalvalueoftheinvokingconstantwithanotherconstan
tof the same enumeration.
Returnsanegativevalueiftheinvokingconstant'sordinalvalueislessthan
the other constant's, zero if they're equal, and a positive value if it's
greater.
Exampl Apple.Jonathan.compareTo(Apple.RedDel) wouldreturnanegative
e:
value.
equals()Method: equals() methoddefinedbyObject.
Overridesth
e
Comparesanenumerationconstantwithanyother object.
Returnstrueonlyifbothobjectsrefertothesameconstantwithinthesa
me enumeration.
Example:Apple.Jonathan.equals(Apple.Jonathan)wouldreturntrue.
:
3. ComparingEnumerationConstants
Enumerationconstantscanbecomparedfor equalityusingtheoperator.
==
Themethodcanalsobeusedtocompareconstantsforequality,ensuring they belong to the s
equals()
:
Demonstrates the usage of ordinal(), compareTo(), andmethodswith enumeration const
4. ExampleProgram
equals()
//Demonstrateordinal(),compareTo(),andequals().
classEnumDemo4{
publicstaticvoidmain(String[]args)
{
Appleap,ap2,ap3;
//Obtainallordinalvaluesusingordinal().System.out.println("Hereareallappleconstants" +
"andtheirordinalvalues:");for(Applea:Apple.values()) System.out.println(a +
"" + a.ordinal());
ap =Apple.RedDel; ap2 =
Apple.GoldenDel; ap3 =
Apple.RedDel;
System.out.println();
//DemonstratecompareTo()andequals()if(ap.compareTo(ap2)<0)
System.out.println(ap + " comes before " + ap2);
if(ap.compareTo(ap2)>0)
System.out.println(ap2+"comesbefore"+ap);
System.out.println();if(ap.equals(ap2))
System.out.println("Error!");
if(ap.equals(ap3))
System.out.println(ap+"equals"+ap3);
if(ap==ap3)
System.out.println(ap+"=="+ap3);
}
}
Theoutputfromtheprogramisshownhere:
Hereareallappleconstantsandtheirordinalvalues:Jonathan0
GoldenDel1
RedDel2
Winesap3
Cortland4
GoldenDelcomesbeforeRedDelRedDel equals
RedDel
AnotherEnumerationExample
An automated “decision maker” program was created. In that version, variables called NO, YES,
MAYBE, LATER, SOON, and NEVER were declared within an interface and used to represent the
possibleanswers.Whilethereisnothingtechnicallywrong withthatapproach,
theenumerationisabetterchoice.Hereisanimprovedversionofthatprogramthatusesanenumcalled
Answerstodefinetheanswers.
//Animprovedversionofthe"DecisionMaker"
//programfromChapter9.Thisversionusesan
//enum,ratherthaninterfacevariables,to
// represent the answers. import
java.util.Random;
//Anenumerationofthepossibleanswers.enumAnswers{ NO,
YES, MAYBE, LATER, SOON, NEVER
}
classQuestion{
Randomrand=newRandom();Answersask(){ int
prob = (int) (100 * rand.nextDouble());
if(prob<15)
returnAnswers.MAYBE;//15%elseif
(prob < 30)
return Answers.NO; // 15%
else if (prob < 60)
returnAnswers.YES; //30%
elseif(prob<75)
returnAnswers.LATER;//15%elseif (prob
< 98)
returnAnswers.SOON;//13%else
return Answers.NEVER; // 2%
}
}
classAskMe{
staticvoidanswer(Answersresult){switch(result)
{ case NO: System.out.println("No"); break;
case YES: System.out.println("Yes"); break;
case MAYBE: System.out.println("Maybe");
break;
caseLATER:System.out.println("Later");break;
case SOON: System.out.println("Soon"); break;
caseNEVER:System.out.println("Never");break;
}
}
publicstaticvoidmain(String[]args){Questionq=new Question();
answer(q.ask());
answer(q.ask());
answer(q.ask());
answer(q.ask());
}
}
TypeWrappers
Javaprovidestypewrapperclassesthatencapsulateprimitivetypeswithinobjects.
Typewrapperclassesinclude Double, Float, Long, Integer, Short, Byte, Charact
TheseclassesoffermethodsthatallowintegrationofprimitivetypesintoJava'sobject hi
Java'sautoboxingfeatureautomaticallyconvertsprimitivetypestotheircorresponding
Thissimplifiestheprocessofworkingwithbothprimitivetypesandobjects,as conversio
Overall,typewrappersinJavaallowprimitivetypestobeusedinsituationswhereobjectsar
objectsbyhandlingconversionsautomatically.
Character
Characterisawrapperaroundachar.Theconstructor forCharacterisCharacter(charch)
Here,chspecifiesthecharacterthatwillbewrappedbytheCharacterobjectbeingcreated.
However,beginningwithJDK9,theCharacterconstructorwasdeprecated,andbeginningwithJDK16,it has
been deprecated for removal. Today, it is strongly recommended that you use the static method
valueOf( ) to obtain a Character object.
Itisshown here:
staticCharactervalueOf(charch)
ItreturnsaCharacterobjectthatwrapsch.
ToobtainthecharvaluecontainedinaCharacterobject,callcharValue(),shownhere:char charValue( )
Itreturnstheencapsulatedcharacter.
Boolean
Booleanisawrapperaroundbooleanvalues.Itdefinestheseconstructors:
Boolean(boolean boolValue)
Boolean(String boolString)
Inthe first version, boolValuemustbe either trueor false. Inthe second version, ifboolString contains
thestring"true"(inuppercaseorlowercase),thenthenewBooleanobjectwillbetrue.Otherwise,itwill be false.
However,beginningwithJDK9,theBooleanconstructorsweredeprecated,andbeginningwithJDK16,
theyhavebeendeprecatedforremoval.Today,itisstronglyrecommendedthatyouusethestaticmethod
valueOf( ) to obtain a Boolean object. It has the two versions shown here:
EachreturnsaBooleanobjectthatwrapstheindicatedvalue.
ToobtainabooleanvaluefromaBooleanobject,usebooleanValue(),shownhere:booleanbooleanValue( )
Itreturnsthe booleanequivalentof theinvokingobject.
TheNumericTypeWrappers
The mostcommonly used type wrappersare those thatrepresent numeric values. These are Byte,
Short, Integer, Long, Float, and Double.
All of the numeric type wrappers inherit the abstract class Number. Number declares methods
that return the value of an object in each of the different number formats.
Thesemethodsareshownhere:
byte byteValue( )
doubledoubleValue()
float floatValue( )
int intValue( )
long longValue( )
shortshortValue()
For example, doubleValue( ) returns the value of an object as a double, floatValue( ) returns
the value as a float, and so on.
Thesemethodsareimplementedbyeachofthenumerictypewrappers.
Allof thenumerictypewrappersdefineconstructorsthatallow an objecttobeconstructed from a
given value, or a string representation of that value.
Forexample,herearetheconstructorsdefinedfor Integer:
Integer(int num)
Integer(Stringstr)
Ifstrdoesnotcontainavalidnumericvalue,thenaNumberFormatExceptionisthrown.
HerearetwooftheformssupportedbyInteger:
staticIntegervalueOf(intval)
staticIntegervalueOf(StringvalStr)throwsNumberFormatException
Here, val specifies an integer value and valStr specifies a string that represents a properly formatted numeric
value in string form. Each returns an Integer object that wraps the specified value. Here is an example:
IntegeriOb=Integer.valueOf(100);
After this statement executes, the value 100 is represented by an Integer instance. Thus, iOb wraps the value
100 within an object. In addition to the forms valueOf( ) just shown, the integer wrappers, Byte, Short,
Integer, and Long, also supply a form that lets you specify a radix.
All of the type wrappers override toString( ). It returns the human-readable form of the value contained within
the wrapper. This allows you to output the value by passing a type wrapperobject to println(), for
example,withouthavingtoconvertitintoitsprimitivetype.
Thefollowingprogramdemonstrates howto usea numeric type wrappertoencapsulate a value and then extract that
value.
//Demonstrateatypewrapper. class
Wrap {
publicstaticvoidmain(String[]args){IntegeriOb=
Integer.valueOf(100);inti=iOb.intValue();
System.out.println(i+""+iOb);//displays100100
}
}
Thisprogramwrapstheintegervalue100insideanIntegerobjectcallediOb.Theprogramthenobtainsthisvaluebycalling
intValue()andstorestheresultini.
The process of encapsulating a value within an object is called boxing. Thus, in the program, this line boxes the
value 100 into an Integer:
IntegeriOb=Integer.valueOf(100);
The process of extracting a value from a type wrapper is called unboxing. For example, the program unboxes
the value in iOb with this statement:
inti= iOb.intValue();
The same general procedure used by the preceding program to box and unbox values has been available for use
sincetheoriginalversionofJava.However,today,Javaprovidesamorestreamlined approach, whichisdescribed next.
Autoboxing
ModernversionsofJavahaveincludedtwoimportantfeatures:autoboxingandauto-unboxing.
Autoboxing is the process by which a primitive type is automatically encapsulated (boxed) into its
equivalent type wrapper whenever an object ofthat type is needed.
There isno need to explicitly construct anobject. Auto-unboxingisthe process bywhich the value ofa
boxed object isautomatically extracted (unboxed) froma type wrapper whenitsvalue is needed.
ThereisnoneedtocallamethodsuchasintValue()ordoubleValue().
Autoboxingandauto-unboxinggreatlystreamlinethecodingofseveralalgorithms, removingthetedium of
manually boxing and unboxing values.
They also help prevent errors. Moreover, they are very important to generics, which operate only on
objects.Finally,autoboxingmakesworkingwiththeCollectionsFramework
Withautoboxing,itisnotnecessarytomanuallyconstructanobjectinordertowrapaprimitivetype.You
needonlyassignthatvaluetoatype-wrapperreference.Javaautomaticallyconstructstheobjectforyou. For
example, here isthe modern wayto construct anInteger object that has the value 100:
IntegeriOb=100;//autoboxanint
Noticethattheobjectisnotexplicitlyboxed.Javahandlesthisforyou,automatically.
Tounboxanobject,simplyassignthatobjectreferencetoaprimitive-typevariable.
Forexample,tounboxiOb,youcanusethis line:
inti=iOb;//auto-unbox
Javahandlesthedetailsforyou.
Hereistheprecedingprogramrewrittentouseautoboxing/unboxing:
//Demonstrateautoboxing/unboxing.classAutoBox{
publicstaticvoidmain(String[]args){ Integer iOb =100;// autobox
System.out.println(i+""+iOb);//displays100100
}
}
AutoboxingandMethods
//Autoboxing/unboxingtakesplace with
//methodparametersandreturnvalues.
class AutoBox2{
//TakeanIntegerparameterandreturn
//anintvalue;
staticintm(Integerv) {
returnv;//auto-unboxtoint
}
publicstaticvoidmain(String[]args){
//Passaninttom()andassignthereturnvalue
//toanInteger.Here,theargument100isautoboxed
//intoanInteger.Thereturnvalueisalsoautoboxed
// into an Integer.
IntegeriOb=m(100);
System.out.println(iOb);
}
}
100
Autoboxing/UnboxingOccursinExpressions
In general, autoboxing and unboxing take place whenever a conversion into an object or from an object is
required. Thisappliesto expressions. Withinanexpression, a numericobjectisautomaticallyunboxed.The
outcomeoftheexpressionisreboxed,ifnecessary. For example, consider the following program:
//Autoboxing/unboxingoccurs insideexpressions.
class AutoBox3 {
publicstaticvoidmain(String[]args){
IntegeriOb,iOb2;inti;
iOb = 100;
System.out.println("OriginalvalueofiOb:"+iOb);
//Thefollowingautomatically unboxesiOb,
//performstheincrement,andthenreboxes
//theresultbackintoiOb.
++iOb;
System.out.println("After++iOb:"+iOb);
//Here,iObisunboxed,theexpressionis
//evaluated,andtheresultisreboxedand
// assigned to iOb2. iOb2 = iOb +
(iOb / 3);
System.out.println("iOb2afterexpression:"+iOb2);
//Thesameexpressionisevaluated,butthe
//resultisnotreboxed.i=iOb+ (iOb
/3);
System.out.println("iafterexpression:"+i);
}
}
Theoutputisshownhere:
OriginalvalueofiOb:100After
++iOb:101
iOb2afterexpression:134iafter expression:
134
Intheprogram,payspecialattentiontothisline:
++iOb;
Thiscauses the value in iObto be incremented. It works like this: iOb is unboxed, the value is
incremented, and the result is reboxed.
Auto-unboxingalsoallowsyoutomixdifferenttypesofnumericobjectsinanexpression. Once
the values are unboxed, the standard type promotions and conversions are applied. For
example, the following program is perfectly valid:
class AutoBox4{
publicstaticvoidmain(String[]args){
IntegeriOb=100;DoubledOb
=98.6;
dOb=dOb+iOb;
System.out.println("dObafterexpression:"+dOb);
}
}
Theoutputisshownhere:
dOb afterexpression:198.6
As you can see, both the Double object dOb and the Integer object iOb participated in the addition,
and the result was reboxed and stored in dOb.
Becauseofauto-unboxing,youcan use Integernumeric objectstocontrola switch
statement. Forexample,considerthisfragment:
IntegeriOb=2;switch(iOb){
case1:System.out.println("one");break;
case2:System.out.println("two");break;
default:System.out.println("error");
}
Autoboxing/UnboxingBooleanandCharacterValues
Java also supplies wrappers for boolean and char. These are Boolean and Character.
Autoboxing/unboxing applies to these wrappers, too. For example, consider the following
program:
//Autoboxing/unboxingaBooleanandCharacter.
classAutoBox5{
publicstaticvoidmain(String[]args){
//Autobox/unboxaboolean.Booleanb= true;
//Below,bisauto-unboxedwhenusedin
// a conditional expression, such as an if. if(b)
System.out.println("b is true");
System.out.println("ch2is"+ch2);
}
}
Theoutputisshownhere:
bistrue ch2 is
x
Autoboxing/UnboxingHelpsPrevent Errors
Inadditiontotheconveniencethatitoffers,autoboxing/unboxingcanalsohelppreventerrors.Forexample, consider the
following program:
//Anerrorproducedbymanualunboxing.class UnboxingError {
publicstaticvoidmain(String[]args){
IntegeriOb=1000;//autoboxthevalue1000
inti=iOb.byteValue();//manuallyunboxasbyte!!!
System.out.println(i);//doesnotdisplay1000 !
}
}