0% found this document useful (0 votes)
91 views

Race Condition in Java Multithreading

Race condition in Java occurs when multiple threads try to access and modify a shared resource at the same time. This can cause unexpected behavior as the order of operations becomes non-deterministic. The example demonstrates a race condition where three threads increment and decrement a shared counter variable, resulting in incorrect values. To fix this, the access to the shared resource needs to be synchronized so that only one thread can access it at a time. Synchronizing the run() method blocks prevents the race condition.

Uploaded by

ANKUSH NEGI
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
91 views

Race Condition in Java Multithreading

Race condition in Java occurs when multiple threads try to access and modify a shared resource at the same time. This can cause unexpected behavior as the order of operations becomes non-deterministic. The example demonstrates a race condition where three threads increment and decrement a shared counter variable, resulting in incorrect values. To fix this, the access to the shared resource needs to be synchronized so that only one thread can access it at a time. Synchronizing the run() method blocks prevents the race condition.

Uploaded by

ANKUSH NEGI
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Race Condition in Java Multi-Threading

 Race condition in Java occurs in a multi -threaded


environment when more than one thread try to access a
shared resource (modify, write) at the sa me time.
 Since multiple threads try to race each other to finish
executing a method thus the name race condition .
 Two points to note about race condition are -

 It is safe if multiple threads are trying to read a shared


resource as long as they are not trying to change it.
 Multiple threads executing inside a method is not a
problem in itself, problem arises when these threads try to
access the same resource.

 Examples of shared resources are class variables, DB


record in a table, writing in a file.
 Example of race condition in Java
 Let’s see one example of race condition in Java multi -
threading, where we have a shared instance variable .
Since there are three threads shari ng the same object of the
class so the field in the object is shared among the threads.
 This instance variable c is incremented and decremented
so every thread should leave it in the state it initially was
i.e. if c is zero in the start, incrementing it will make it 1
and decrementing it will make it zero again.
 Here some delay is simulated u sing sleep(), as in a real
production system there may be many processes running
and many users might be accessing the same application at
any given time. In that kind of scenario we can’t be sure of
when context switching will happen among the threads
contending for CPU-cycle. That’s why race condition
related bugs are very difficult to find and you may not be
even able to reproduce them as that kind of context -
switching may not happen when you are trying to
reproduce the race condition related error.
Java code

class Coun te r imple ment s Run na ble{


p ri va te in t c = 0;

p ublic voi d in creme nt () {


t ry {
Threa d. sleep (10);
} ca t ch (In te rrupt e dE xcep ti on e ) {
// TODO Auto - ge ne ra te d cat ch b lock
e.p rint Sta ckTrace ();
}
c++;
}

p ublic voi d de creme nt () {


c--;
}

p ublic i nt ge tVa lue () {


ret urn c;
}

@ Ove rri de
p ublic voi d run () {
//in cre ment in g
t hi s.in cre ment ();
S yste m.out.p ri nt ln ("Va lue for Thread Afte r i ncrement "
+ Threa d. curre ntThrea d (). ge tNa me () + " " + t hi s. ge tVa lue ());
//de cre me nti n g
t hi s. de cre me nt ();
S yste m.out.p ri nt ln ("Va lue for Thread a t la st "
+ Threa d. curre ntThrea d (). ge tNa me () + " " + t hi s. ge tVa lue ());
}
}

p ub li c class Ra ce Con dit ionDe mo


{
p ublic sta ti c voi d ma in (St rin g [] a rgs )
{
Coun te r count e r = ne w Counte r ();
Thre a d t 1 = n e w Threa d (count er , "Threa d -1");
Thre a d t 2 = n e w Threa d (count er , "Threa d -2");
Thre a d t 3 = n e w Threa d (count er , "Threa d -3");
t1.sta rt ();
t 2.sta rt();
t 3.sta rt();
}
}
Output

Va lue for Threa d Aft e r in cre me nt Threa d -2 3


Va lue for Threa d a t last Thre a d-2 2
Va lue for Threa d Aft e r in cre me nt Threa d -1 2
Va lue for Threa d a t last Thre a d-1 1
Va lue for Threa d Aft e r in cre me nt Threa d -3 1
Va lue for Threa d a t last Thre a d-3 0

It ca n b e se en how t he sha re d va riab le c i s gi vi n g wron g va lue s .

Using synchronization to avoid race


condition in Java
To fi x t he ra ce con di ti on we nee d to have a wa y to re str ict re sou r ce a cce ss
to on ly one t hrea d at a tim e. We ha ve t o use synchroni ze d ke yword t o
syn chron i ze t he access t o the sha re d re source . L et ’s see t he sa me
e xa mple a ga in wit h p rope r syn chroni za t i on t o a voi d ra ce con di ti on .

c l as s Cou nt er i m p lem e n ts Ru nn a ble {


p ri v at e i n t c = 0 ;
pu b li c voi d i nc rem en t ( ) {
tr y {
T hr ead .s le ep (1 0 );
} c a tc h ( In te rr up te dE xc e pti on e) {
/ / T OD O Au to - gen e rat ed c a tc h bloc k
e. pri n tS t ac kT rac e () ;
}
c++;
}
pu b li c voi d dec rem e n t ( )
{
c--;
}

p u bli c i n t ge tV al ue ()
{
ret ur n c ;
}

@ O ver ri d e
pu b li c voi d ru n ()
{
s ync hro ni z ed (thi s )
{
/ / i nc rem e n ti n g
this.increment();
S ys tem .ou t. pri nt ln ( "V a lue f or T hr ead A f ter i nc rem e nt "
+ T hre ad .c ur re nt T hre ad () . ge tN am e () + " " + t hi s . ge tV a lu e ( )) ;
/ /dec rem e n ti ng
thi s .d ec rem en t ( ) ;
S ys tem .ou t. pri nt ln ( "V a lue f or T hr ead a t l as t " +
T h rea d .c u rr en tT hr ead ( ). ge tN am e () + " " + t hi s . ge tV al ue () );
}
}
}

p u bli c c l as s Rac eCo ndi ti o nD em o


{
pu b li c s ta ti c voi d m ai n (S t ri n g[ ] a rgs )
{
Co un te r c ou nt er = n e w Cou nt er () ;
T h rea d t1 = ne w T h rea d (c ou nte r , "T hr ea d - 1 ") ;
T h rea d t2 = ne w T h rea d (c ou nte r , "T hr ea d - 2 ") ;
T h rea d t3 = ne w T h rea d (c ou nte r , "T hr ea d - 3 ") ;
t1.s ta rt ( );
t2.s ta rt ( );
t3.s ta rt ( );
}
}

O ut p ut

V al ue for T hre ad A f te r i ncrem en t Thr ead - 2 1


V al ue for T hre ad a t l a st Th rea d- 2 0

V al ue for T hre ad A f te r i ncrem en t Thr ead - 3 1


V al ue for T hre ad a t l a st Th rea d- 3 0

V al ue for T hre ad A f te r In cre men t T hre ad - 1 1


V al ue for T hre ad a t l a st Th rea d- 1 0

I t c an b e seen fr om the ou tpu t h o w th re ads are a cce ssin g the sh ared


r es ou rc e on e a t a ti me no w. Synchr onizin g the access wi th in th e run ()
m e th od m ade i t ha ppen .

You might also like