Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
227 views

Multithreading in Java

The document discusses multithreading in Java. It defines threads as pieces of code that run concurrently with other threads within a single process and share the same memory space. It describes how to create threads by extending the Thread class or implementing the Runnable interface. It also discusses thread states, synchronization, and methods of the Thread class like start(), run(), join(), sleep(). Examples are provided to illustrate printing output from multiple threads and passing data between threads.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
227 views

Multithreading in Java

The document discusses multithreading in Java. It defines threads as pieces of code that run concurrently with other threads within a single process and share the same memory space. It describes how to create threads by extending the Thread class or implementing the Runnable interface. It also discusses thread states, synchronization, and methods of the Thread class like start(), run(), join(), sleep(). Examples are provided to illustrate printing output from multiple threads and passing data between threads.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 59

Multithreading

National Institute of Technology Puducherry


Manjith B.C.
What are Threads?
• A piece of code that run in concurrent with other threads.
• Each thread is a statically ordered sequence of instructions.
• Threads are being extensively used express concurrency on both
single and multiprocessors machines.
• Programming a task having multiple threads of control –
Multithreading or Multithreaded Programming.

2
Advantages of Multithreading
• Reactive systems – constantly monitoring
• More responsive to user input – GUI application can interrupt a
time-consuming task
• Server can handle multiple clients simultaneously
• Can take advantage of parallel processing
• Different processes do not share memory space.
• A thread can execute concurrently with other threads within a single
process.
• All threads managed by the JVM share memory space and can
communicate with each other.
A single threaded program
class ABC
{
….
public void main(..) begin
{
… body
..
} end

5
A Multithreaded Program

Main Thread

start
start start

Thread Thread
A Thread B
C

Threads may switch or exchange data/results


6
Single and Multithreaded Processes
threads are light-weight processes within a process

Single-threaded Process Multiplethreaded Process


Threads of
Execution

Single instruction stream Common Multiple instruction stream


Address Space

7
Multithreaded Server: For Serving Multiple
Clients Concurrently

Client 1 Process Server Process

Server
Threads
■ Internet

Client 2 Process

8
Modern Applications need Threads (ex1):
Editing and Printing documents in background.
Printing Thread

Editing Thread

9
Threads in Java
Creating threads in Java:

• Extend java.lang.Thread class


OR
• Implement java.lang.Runnable interface

10
Threads in Java
Creating threads in Java:
• Extend java.lang.Thread class
• run() method must be overridden (similar to main method of sequential
program)
• run() is called when execution of the thread begins
• A thread terminates when run() returns
• start() method invokes run()
• Calling run() does not create a new thread
• Implement java.lang.Runnable interface

11
Threads in Java
Creating threads in Java:
• Extend java.lang.Thread class
• Implement java.lang.Runnable interface
• If already inheriting another class (i.e., JApplet)
• Single method: public void run()
• Thread class implements Runnable.

12
Thread States

13
Implementing Runnable
class Thread1 implements Runnable
{
public void run()
{
System.out.println("Hello");
}
}
class ThreadDemo
{
public static void main(String args[])
{
Thread1 ob1=new Thread1();
Thread t1=new Thread(ob1);
t1.start();
}
}
Write a program to create two threads from
the same method
class Thread1 implements Runnable
{
public void run()
{
System.out.println("Hello");
}
}
class ThreadDemo
{
public static void main(String args[])
{
Thread1 ob1=new Thread1();
Thread t1=new Thread(ob1);
t1.start();
Thread1 ob2=new Thread1();
Thread t2=new Thread(ob2);
t2.start();
}
}
Creating threads from multiple methods
class Thread1 implements Runnable
{
public void run()
{
System.out.println("Hello");
}
}
class Thread2 implements Runnable
{
public void run()
{
System.out.println("Hai");
}
}
class ThreadDemo
{
public static void main(String args[])
{
Thread1 ob1=new Thread1();
Thread t1=new Thread(ob1);
t1.start();
Thread2 ob2=new Thread2();
Thread t2=new Thread(ob2);
t2.start();
}
}
Write a program to print numbers 1 to 20 in
one thread and 21 to 40 in another thread
class thread1 implements Runnable
{
public void run()
{
for(int i=1;i<=20;i++)
{
System.out.println("Thread 1 : "+ i);
}
}
}
class thread2 implements Runnable
{
public void run()
{
for(int j=21;j<=40;j++)
System.out.println("Thread 2 : "+ j);
}
}
public class Demo_thread {
public static void main(String args[])
{
thread1 ob1=new thread1();
Thread tx=new Thread(ob1);
tx.start();
thread2 ob2=new thread2();
Thread ty=new Thread(ob2);
ty.start();
}
}
Extending Thread
class thread1 extends Thread
{
public void run()
{
for(int i=1;i<=20;i++)
{
System.out.println("Thread 1 : "+ i);
}
}
}
class thread2 extends Thread
{
public void run()
{
for(int j=21;j<=40;j++)
System.out.println("Thread 2 : "+ j);
}
}
public class Demo_Thread2 {
public static void main(String args[])
{
thread1 ob1=new thread1();
ob1.start();
thread2 ob2=new thread2();
ob2.start();
}

}
Java.lang.Thread class in Java

• Field
Following are the fields for java.lang.Thread class −
• static int MAX_PRIORITY − This is the maximum priority that a thread can
have.
• static int NORM_PRIORITY − This is the default priority that is assigned to a
thread.
Method & Description
static int activeCount()This method returns the number of active
threads in the current thread's thread group.
static Thread currentThread()This method returns a reference to the
currently executing thread object.
long getId()This method returns the identifier of this Thread.
String getName()This method returns this thread's name.
int getPriority()This method Returns this thread's priority.
State getState()This method returns the state of this thread.
boolean isAlive()This method tests if this thread is alive.
void join()Waits for this thread to die.
void run()If this thread was constructed using a separate Runnable run
object, then that Runnable object's run method is called; otherwise, this
method does nothing and returns
void setName(String name)This method changes the name of this thread to
be equal to the argument name.
void setPriority(int newPriority)This method changes the priority of this
thread.
static void sleep(long millis)This method causes the currently executing
thread to sleep (temporarily cease execution) for the specified number of
milliseconds, subject to the precision and accuracy of system timers and
schedulers.
static void sleep(long millis, int nanos)This method causes the currently
executing thread to sleep (cease execution) for the specified number of
milliseconds plus the specified number of nanoseconds, subject to the
precision and accuracy of system timers and schedulers.
void start()This method causes this thread to begin execution; the Java
Virtual Machine calls the run method of this thread.
Example 2
class thread1 extends Thread
{
public void run()
{
try
{
for(int i=11;i<=20;i++)
{
System.out.println("Thread 1 : "+ i);
Thread.sleep(100);
}
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
}
class thread2 extends Thread
{
public void run()
{
try
{
for(int j=100;j<=200;j+=10)
System.out.println("Thread 2 : "+ j);
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
}
class example_thread
{
public static void main(String args[])
{
thread1 ob1=new thread1();
ob1.start();
thread2 ob2=new thread2();
ob2.start();
try
{
for(int x=50;x<=100;x=x+10)
{
System.out.println("Main Thread : "+ x);
Thread.sleep(50);
}
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
}
• Write a program to print even numbers and odd numbers from 1 to
100 in two different threads
• Write a program to perform selection sort and bubble sort of an array
in two different threads
Printing name and id of threads
class thread1 extends Thread
{
public void run()
{
System.out.println("Id of current thread:"+ Thread.currentThread().getId());
System.out.println("Name of current thread:"+ Thread.currentThread().getName());
}
}
public class Demo_Thread2 {
public static void main(String args[])
{
thread1 ob1=new thread1();
ob1.start();
}
}
Write a program to print id and name of two
threads
Using isAlive( ) and join( )
class NewThread implements Runnable {
String name; // name of thread
Thread t;
NewThread(String threadname)
{
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
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.");
}
}
class DemoJoin {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
NewThread ob3 = new NewThread("Three");
System.out.println("Thread One is alive: "+ ob1.t.isAlive());
System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Thread One is alive: "+ ob1.t.isAlive());
System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
System.out.println("Main thread exiting.");
}
}
Output
New thread: Three: 3
Thread[One,5,main] One: 2
New thread:
Thread[Two,5,main] Two: 2
New thread: Three: 2
Thread[Three,5,main] One: 1
Thread One is alive: true Two: 1
Thread Two is alive: true
Thread Three is alive: Three: 1
true Two exiting.
Waiting for threads to Three exiting.
finish. One exiting.
One: 5
Two: 5 Thread One is alive: false
Three: 5 Thread Two is alive: false
One: 4 Thread Three is alive: false
Two: 4 Main thread exiting.
Three: 4
One: 3
Two: 3
Thread Priorities
• Thread priorities are used by the thread scheduler to decide when
each thread should be allowed to run
• CPU time that a thread gets often depends on several factors besides
its priority
• A higher-priority thread can also preempt a lower-priority one.
• final void setPriority(int level) ---Thread
• level: MIN_PRIORITY -1
• : MAX_PRIORITY -10
• : NORM_PRIORITY -5
final int getPriority( )
Synchronization
• When two or more threads need access to a shared resource, they
need some way to ensure that the resource will be used by only one
thread at a time. The process by which this is achieved is called
synchronization.
// This program is not synchronized

class Callme
{
void call()
{
for(int i=0;i<10;i++)
{
System.out.print(" "+i+" ");
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
}
}
}
class Caller implements Runnable
{
Callme target;
public Caller(Callme targ)
{
target = targ;
} Output
public void run() 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8
{
target.call(); 8 9 9 9
}
}
class Synch
{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target);
Thread t1=new Thread(ob1);
t1.start();
Caller ob2 = new Caller(target);
Thread t2=new Thread(ob2);
t2.start();
Caller ob3 = new Caller(target);
Thread t3=new Thread(ob3);
t3.start();
}
}
• By calling sleep( ), the call( ) method allows execution to switch to
another thread. This results in the mixed-up output of the three
threads. In this program, nothing exists to stop all three threads from
calling the same method, on the same object, at the same time. This
is known as a race condition, because the three threads are racing
each other to complete the method.
• Synchronization can be done in two ways
• Using Synchronized methods
• Using Synchronized statements
Using Synchronized Methods
• While a thread is inside a synchronized method, all other threads that try
to call it on the same instance have to wait. To fix that problem in previous
program, serialize access to call( ) method. That is restrict its access to only
one thread at a time. To do this call( )’s definition is preceded with the
keyword synchronized, as shown here:

class Callme
{
synchronized void call(String msg)
{
...
Example:
class Callme
{
synchronized void call()
{
for(int i=0;i<10;i++)
{
System.out.print(“ “+i+” “);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
}
}
}
class Caller implements Runnable
{
Callme target;
public Caller(Callme targ)
{ Output:
target = targ;
}
public void run() 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
{ 3 4 5 67 8 9
target.call();
}
}
class Synch
{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target);
Thread t1=new Thread(ob1);
t1.start();
Caller ob2 = new Caller(target);
Thread t2=new Thread(ob1);
t2.start();
Caller ob3 = new Caller(target);
Thread t3=new Thread(ob1);
t3.start();
}
}
Using the synchronized Statement
• Put calls to the methods defined by this class inside a synchronized
block.

This is the general form of the synchronized statement:

synchronized(object)
{
// statements to be synchronized
}
Example:
class Callme
{
void call()
{
for(int i=0;i<10;i++)
{
System.out.println(i);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}
System.out.println(",");
}
}
}
class Caller implements Runnable
{
Callme target;
public Caller(Callme targ)
{
target = targ; Output:
}
public void run() 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
{ 6 7 8 9
synchronized(target){
target.call();}
}
}
class Synch
{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target);
Thread t1=new Thread(ob1);
t1.start();
Caller ob2 = new Caller(target);
Thread t2=new Thread(ob2);
t2.start();
Caller ob3 = new Caller(target);
Thread t3=new Thread(ob2);
t3.start();
}
}
Interthread Communication
• unconditionally blocked other threads from asynchronous access to
certain methods
• Used implicit monitors in Java objects
Wait(), notify() and notifyAll()
• wait( ) tells the calling thread to give up the monitor and go to sleep
until some other thread enters the same monitor and calls notify( ) or
notifyAll( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same
object. One of the threads will be granted access.
// An incorrect implementation of a producer
and consumer.
class Q {
int n;
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}
}
class Producer implements Runnable {
Q q;
Producer(Q q)
{
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q)
{
this.q = q;
new Thread(this, "Consumer").start();
}
public void run()
{
while(true)
{
q.get();
}
}
}
class PC {
public static void main(String args[])
Output
{ Put: 1
Got: 1
Q q = new Q(); Got: 1
Got: 1
new Producer(q); Got: 1
Got: 1
new Consumer(q); Put: 2
Put: 3
System.out.println("Press Control-C to stop."); Put: 4
} Put: 5
Put: 6
} Put: 7
Got: 7
// A correct implementation of a producer and
consumer
class Q {
int n;
boolean valueSet = false;
synchronized int get()
{
while(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n)
{
while(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable
{
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable
{
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true)
{
q.get();
}
}
}
class PCFixed {
public static void main(String args[]) { Output
Q q = new Q(); Put: 1
Got: 1
new Producer(q); Put: 2
Got: 2
new Consumer(q); Put: 3
Got: 3
System.out.println("Press Control-C to stop."); Put: 4
Got: 4
} Put: 5
Got: 5
}

You might also like