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

Threads: Three Loops Sequential Execution

Threads allow for multitasking within a program by executing multiple tasks simultaneously through concurrency and sharing a common memory space, with threads mapped to operating system threads under the hood. Java provides built-in threading support through the Thread class which allows creating threads either by implementing the Runnable interface or extending the Thread class directly. Threads have priorities that determine scheduling order, with higher priority threads preferred over lower priority ones.

Uploaded by

Aaine Siddiqui
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
44 views

Threads: Three Loops Sequential Execution

Threads allow for multitasking within a program by executing multiple tasks simultaneously through concurrency and sharing a common memory space, with threads mapped to operating system threads under the hood. Java provides built-in threading support through the Thread class which allows creating threads either by implementing the Runnable interface or extending the Thread class directly. Threads have priorities that determine scheduling order, with higher priority threads preferred over lower priority ones.

Uploaded by

Aaine Siddiqui
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Threads

„ The ability to do multiple things at once within the same


application
„ Finer granularity of concurrency
Multithreading „ Lightweight
„ Easy to create and destroy
„ Shared address space
„ Can share memory variables directly
„ May require more complex synchronization logic because of
shared address space

25-Oct-05 2

Example Code: ThreeLoopTest


public class ThreeLoopTest {
public static void main (String args[ ]){

Three Loops // first loop


for (int i=1; i<= 5; i++)
Sequential Execution System.out.println(“first ” +i);

// second loop
for (int j=1; j<= 5; j++)
System.out.println(“second ” + j);

// third loop
for (int k=1; k<= 5; k++)
System.out.println(“third ” + k);

}
}
25-Oct-05 4

Compile & Execute: ThreeLoopTest Multi-Threaded Output

5 6

1
Java Threads Creating Threads in Java
„ Java includes built-in support for threading! „ Two approaches
„ Other languages have threads bolted-on to an existing structure „ Using Interface
„ Implement the runnable interface in a class
„ VM transparently maps threads in Java to OS threads „ Provide an implementation for the run() method
„ Allows threads in Java to take advantage of hardware and operating system „ Instantiate Thread object by passing runnable object in constructor
level advancements „ Start thread
„ Keeps track of threads and schedules them to get CPU time
„ Scheduling may be pre-emptive or cooperative
„ Using Inheritance
„ Subclass java.lang.Thread
„ Override the run() method
„ Instantiate Subclass Thread Object
„ Start thread

7 8

Thread Creation Steps : using Interface


„ Step 1 - Implement the Runnable Interface

class Worker implements Runnable

„ Step 2 - Provide an Implementation of run method Three Loops


public void run ( ){ Multi-Threaded Execution
// write thread behavior
// code that will execute by thread
}

„ Step 3 - Instantiate Thread object by passing runnable object in constructor

Worker w = new Worker(“first”);


Thread t = new Thread (w);

„ Step 4 – Start thread


t.start()

9 25-Oct-05

Example Code: using Interface Example Code: using Interface


public class Worker implements Runnable { public class ThreadTest{
public static void main (String args[ ]){
private String job ;
Worker first = new Worker (“first job”);
public Worker (String j ){ Worker second = new Worker (“second job”);
Worker third = new Worker (“third job”)
job = j;
Thread t1 = new Thread (first );
}
Thread t2 = new Thread (second);
Thread t3 = new Thread (third);
public void run ( ) {
for(int i=1; i<= 10; i++) t1.start();
t2.start();
System.out.println(job + " = " + i); t3.start();
} }
}
}
11 12

2
Thread Priorities Thread Priorities
„ Every Thread has a priority „ You can change thread priority by using any of the 3
predefined constants
„ Threads with higher priority are executed in preference
to threads with lower priority „ Thread.MAX_PRIORITY (typically 10)

„ Thread.NORM_PRIORITY (typically 5)
„ A thread’s default priority is same as of the creating Thread.MIN_PRIORITY (typically 1)
thread „

„ OR any integer value between 1 to 10 can be used as


thread priority.

13 14

Useful Thread Methods Thread priority scheduling example


Ready threads

„ setPriority(int priority) Thread.MAX_PRIORITY Priority 10 A B

Priority 9 C

„ Changes the priority of this thread Priority 8

Priority 7 D E F
„ Throws IllegalArgumentException if the priority is not in the range
MIN_PRIORITY to MAX_PRIORITY Priority 6 G

Thread.NORM_PRIORITY Priority 5 H I

„ For Example,
Priority 4

Thread t = new Thread(RunnableObject); Priority 3

t.SetPriority(Thread.MAX_PRIORITY);
Priority 2 J K
t.setPriority(7);
Thread.MIN_PRIORITY Priority 1

15 16

Code Example: PriorityEx.java Output: PriorityEx.java


public class PriorityEx{
public static void main (String args[ ]){
Worker first = new Worker (“first job”);
Worker second = new Worker (“second job”);

Thread t1 = new Thread (first );


Thread t2 = new Thread (second);

t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread. MAX_PRIORITY);

t1.start();
t2.start();
}
}

17 18

3
Thread Priorities
„ Problems

„ A Java thread priority may map differently to the thread


priorities of the underlying OS
Lab Work - Reading Two Files
„ Solaris has 232–1 priority levels;
Simultaneously
„ Windows NT has only 7 user priority levels

„ Starvation can occur for lower-priority threads if the higher-


priority threads never terminate, sleep, or wait for I/O

19 25-Oct-05

Useful Thread Methods (cont.) Useful Thread Methods (cont.)


„ sleep (int time) „ sleep (int time)

„ Causes the currently executing thread to wait for the „ High priority threads should execute sleep method after
time (milliseconds) specified some time to give low priority threads a chance to run
otherwise starvation may occur
„ Waiting is efficient (non-busy)
„ Sleep can be used for delay purpose
„ Threads come out of the sleep when the specified time
interval expires or when interrupted by some other „ i.e., anyone can call Thread.sleep
thread
„ Note that sleep throws InterruptedException. Need try/catch
„ Thread coming out of sleep may go to the running or
ready state depending upon the availability of the
processor.

21 22

Code Example: Modify Worker.java Code Example: SleepEx.java


public class Worker implements Runnable { public class SleepEx{
………….
public static void main (String args[ ]){
public void run ( ) {
for(int i=1; i<= 10; i++) { Worker first = new Worker (“first job”);
try { Worker second = new Worker (“second job”);
Thread.sleep(100);
}catch (Exception ex){ Thread t1 = new Thread (first );
System.out.println(ex);
}
Thread t2 = new Thread (second);
System.out.println(job + " = " + i);
t1.start();
} // end for
} // end run t2.start();
}
}// end Worker }

23 24
Output: SleepEx.java Useful Thread Methods (cont.)
„ yield ( )

„ Allows any other threads of the same priority to execute


(moves itself to the end of the priority queue)

„ If all waiting threads have a lower priority, then the


yielding thread resumes execution on the CPU

„ Generally used in cooperative scheduling schemes

25 26

Code Example: Modify Worker.java Code Example: YieldEx.java


public class Worker implements Runnable { public class YieldEx{

…………. public static void main (String args[ ]){

public void run ( ) { Worker first = new Worker (“first job”);


Worker second = new Worker (“second job”);
for(int i=1; i<= 10; i++) {
Thread.yield( ); Thread t1 = new Thread (first );
Thread t2 = new Thread (second);
System.out.println(job + " = " + i);
} // end for t1.start();
} // end run t2.start();
}
}
}// end Worker
27 28

Output: YieldEx.java Thread States: Life Cycle of a Thread


„ Thread states
„ Born state
„ Thread was just created
„ Ready state
„ Thread’s start method invoked
„ Thread can now execute
„ Running state
„ Thread is assigned a processor and running
„ Dead state
„ Thread has completed or exited
„ Eventually disposed of by system

29 30

5
Thread life-cycle statechart diagram Thread Lifecycle
start()
Born

start new

Ready
I/O completed
ready
thread dispatch notify()
quantum expiration (assign a
yield processor) times expires
timeout expires

I/O completes
blocked

interrupt
notifyAll

interrupt

acquire lock
or interrupted
notify

en dispatch
Running te
r
stasyn
is
re sue te chr
m on waiting yield()
sleeping
qu I
com

es /O en iz
it
p

t t ed
ee

wa sleep()
ple
sl

te

Waiting Sleeping Blocked Block on I/O

wait() running
sleep interval When a thread completes
expires (returns from its run method),
interrupt it reaches the Dead state
(shown here as the final state)
run completes
dead

31 32

Joining Code Example: Modify Worker.java


„ Used when a thread wants to wait for another thread to public class Worker implements Runnable {
complete its run()
………….
„ Sent the thread2.join() message
„ Causes the current running thread to block efficiently until thread2 public void run ( ) {
finishes its run() method
„ Must catch InterruptedException for(int i=1; i<= 10; i++)
System.out.println(job + " = " + i);
}

}// end Worker


33 34

Code Example: JoinEx.java Code Example: JoinEx.java (cont.)


public class JoinEx{
public static void main (String args[ ]){ // The current running thread (main() blocks until both workers have finished
try {
Worker first = new Worker (“first job”); t1.join();
Worker second = new Worker (“second job”); t2.join();
}
Thread t1 = new Thread (first ); catch (Exception ex) {
Thread t2 = new Thread (second); System.out.println(ex);
}
System.out.println("Starting...");
System.out.println("All done ");
t1.start();
t2.start();
}
}
…….
35 36

6
Output: JoinEx.java

Synchronization

37 25-Oct-05

Thread’s Problems Threading


„ Multiple threads can share variables among themselves. „ Two Threading Challenges
„ Mutual Exclusion
Keeping the threads from interfering with each other
This sharing of variables/memory can cause
„
„
„ Worry about memory shared by multiple threads
synchronization problems which you must have studied „ Cooperation
in your OS course. „ Get threads to cooperate
„ Typically centers on handing information from one thread to the

other, or signaling one thread that the other thread has finished
„ The area where shared memory locations are modified doing something
are know as a critical section and only one thread should „ Done using join/wait/notify
able to enter the critical section at any given point in
time.

39 40

Critical Section Race Condition Example


class Pair {
„ A section of code that may cause problems if two or private int a, b;
more threads are executing it at the same time
public Pair() {
„ Typically as a result of shared memory that both thread may a = 0;
be reading or writing b = 0;
}
// Returns the sum of a and b. (reader)
public int sum() {
„ Race Condition return(a+b);
}
„ When two or more threads enter a critical section, they are // Increments both a and b. (writer)
supposed to be in a race condition because the result often public void inc() {
depends upon the order of execution a++;
b++;
„ Both threads want to execute the code at the same time, but if they do }
then bad things will happen }

41 42

7
Reader/Writer Conflict Reader/Writer Conflict
„ Case „ Case
„ thread1 runs inc(), while thread2 runs sum()
„ thread2 could get an incorrect value if inc() is half way done „ thread1 runs inc() while thread2 runs inc() on the same object
„ This happens because the lines of sum() and inc() interleave „ The two inc()’s can interleave in order to leave the object in an
„ Note inconsistent state
„ Even a++ and b++ are not atomic statements
„ Therefore, interleaving can happen at a scale finer than a single statement! „ Again
„ a++ is really three steps: read a, increment a, write a „ a++ is not atomic and can interleave with another a++ to
„ Java guarantees 4-byte reads and writes will be atomic
„ This is only a problem if the two threads are touching the same object and
produce the wrong result
therefore the same piece of memory! „ This is true in most languages

43 44

Heisenbugs Java Locks


„ Random Interleave – hard to observe „ Java includes built- in support for dealing with
„ Race conditions depend on having two or more threads “interleaving” their concurrency issues
execution in just the right way to exhibit the bug
„ Happens rarely and randomly, but it happens „ Includes keywords in order to mark critical sections
„ Interleaves are random „ Includes object locks in order to limit access to a single thread
„ Depending on system load and number of processors when necessary
More likely to observe issue on multi-processor systems
„
„ Java designed to encourage use of threading and
„ Tracking down concurrency bugs can be hard concurrency
„ Reproducing a concurrency bug reliable is itself often hard „ Provides the tools needed in order to minimize concurrency
„ Need to study the patterns and use theory in order to pre-emptively address pitfalls
the issue

45 46

Object Lock and Synchronized keyword Receiver Lock


„ Every Java Object has as lock associated with it „ The lock is in the receiver object
„ A “synchronized” keyword respects the lock of the receiver „ Provides mutual exclusion mechanism for multiple threads
object
sending messages to that object
„ For a thread to execute a synchronized method against a receiver, it must
first obtain the lock of the receiver „ Other objects have their own lock
The lock is released when the method exits
„
„ If a method is not synchronized
„ If the lock is held by another thread, the calling thread blocks (efficiently)
till the other thread exits and the lock is available „ The thread will not acquire the lock before executing the
„ Multiple threads therefore take turns on who can execute against the method
receiver

47 48

8
Sychronized Method Picture Synchronized Method Example
synchronized method -- /*
acquire object lock A simple class that demonstrates using the 'synchronized'
keyword so that multiple threads may send it messages.
thread run { The class stores two ints, a and b; sum() returns
thread run { -- their sum, and inc() increments both numbers.
-- --
-- } <p>
} ivar The sum() and incr() methods are "critical sections" --
they compute the wrong thing if run by multiple threads
ivar at the same time. The sum() and inc() methods are declared
"synchronized" -- they respect the lock in the receiver object.
*/
synch a() { class Pair {
-- private int a, b;
--
} public Pair() {
a = 0;
object lock b = 0;
}

block, waiting for release object lock


object lock

49 50

Synchronized Method Example Synchronized Method Example


// Returns the sum of a and b. (reader) /*
// Should always return an even number. A simple worker subclass of Thread.
public synchronized int sum() { In its run(), sends 1000 inc() messages
return(a+b); to its Pair object.
} */
// Increments both a and b. (writer) class PairWorker extends Thread {
public synchronized void inc() { public final int COUNT = 1000;
a++; private Pair pair;
b++; // Ctor takes a pointer to the pair we use
} public PairWorker(Pair pair) {
} this.pair = pair;
}
// Send many inc() messages to our pair
public void run() {
for (int i=0; i<COUNT; i++) {
pair.inc();
}
}

51 52

Synchronized Method Example Synchronized Method Example


/* // we block until the workers complete
Test main -- Create a Pair and 3 workers. try {
Start the 3 workers -- they do their run() -- w1.join();
and wait for the workers to finish. w2.join();
*/ w3.join();
public static void main(String args[]) { }
Pair pair = new Pair(); catch (InterruptedException ignored) {}
PairWorker w1 = new PairWorker(pair);
PairWorker w2 = new PairWorker(pair); System.out.println("Final sum:" + pair.sum()); // should be 6000
PairWorker w3 = new PairWorker(pair); /*
w1.start(); If sum()/inc() were not synchronized, the result would
w2.start(); be 6000 in some cases, and other times random values
w3.start(); like 5979 due to the writer/writer conflicts of multiple
// the 3 workers are running threads trying to execute inc() on an object at the same time.
// all sending messages to the same object */
}
}

53 54

9
Producer/Consumer Relationship
„ Consider a Producer/Consumer relationship in which a producer
thread deposits a sequence of numbers into a slot of shared
memory

Producer/Consumer Relationship „ The consumer thread reads this data from the shared memory and
prints that data.

„ Problems
„ If the threads are not synchronized, data can be lost if the producer places
new data into the shared slot before the consumer consumes the previous
data

„ Data can be doubled if the consumer consumes the data again before the
producer produces the next item.

25-Oct-05 56

Useful Object Methods


„ wait( )
„ Causes the current running thread to enters a waiting state for the particular
object on which wait( ) was called

Example Code
„ notify( ) / notifyAll( )
„ One thread in the waiting state for a particular object becomes ready on a
Producer/Consumer Relationship call to notify( ) issued by another thread associated with that object.
„ If a thread calls notifyAll( ), then all threads waiting for the object are
placed in the ready state.

„ Every call to wait( ) must have a corresponding call to notify( ) or


call notifyAll( ) as a safeguard.

25-Oct-05 58

An idiom explained even more!


„ Remember:
„ public static void main(String[] args)

Multithreaded Server „ Well…


„ When you run a Java program, the VM creates a new thread
and then sends the main(String[] args) message to the class to
be run!
Lab Exercise
„ Therefore, there is ALWAYS at least one running thread in
existence!
„ We can create more threads which can run concurrently

25-Oct-05 60

10

You might also like