Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Java Threads

Download as pdf or txt
Download as pdf or txt
You are on page 1of 85

JavaThreads

JavaThreads

• Java threads are a way to have different parts of your program


running at the same time.
• For example, you can create an application that accepts input from
different users at the same time, each user handled by a thread.
• Also, most networking applications involve threads
• you would need to create a thread that would wait for incoming messages
while the rest of your program handles your outgoing messages.
Create a java thread

• There are two ways to create a java


thread
• Extending the Thread class
• Implementing the runnable interface
Life Cycle Model of Thread

New: Whenever a new thread is created,


it is always in the new state. For a thread
in the new state, the code has not been
run yet and thus has not begun its
execution.

Active: When a thread invokes the start()


method, it moves from the new state to
the active state. The active state contains
two states within it: one is runnable, and
the other is running.
Thread class
Thread class provide constructors and methods to create and perform operations on a thread. Thread
class extends Object class and implements Runnable interface.
Commonly used Constructors of Thread class are :
Thread()
Thread(String name)
Thread(Runnable r)
Thread(Runnable r,String name)
Commonly used methods of Thread class:
public void run(): is used to perform action for a thread.
public void start(): starts the execution of the thread.JVM calls the run() method on
the thread.
public void join(): waits for a thread to die.
public void join(long miliseconds): waits for a thread to die for the specified
miliseconds.
public int getPriority(): returns the priority of the thread.
public int setPriority(int priority): changes the priority of the thread.
public String getName(): returns the name of the thread.
public void setName(String name): changes the name of the thread.
public Thread currentThread(): returns the reference of currently executing thread.
public int getId(): returns the id of the thread.
public Thread.State getState(): returns the state of the thread.
public boolean isAlive(): tests if the thread is alive.
Commonly used methods of Thread class….

public void yield(): causes the currently executing thread


object to temporarily pause and allow other threads to
execute.
public void suspend(): is used to suspend the
thread(depricated).
public void resume(): is used to resume the suspended
thread(depricated).
public void stop(): is used to stop the thread(depricated).
Java Thread Example by extending Thread class
FileName: Multi.java
class Multi extends Thread{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}
Output: Thread is running
Runnable Interface
• Another way to create a thread is to implement the Runnable
interface.
• This may be desired if you want your thread to extend another
class.
• By extending another class, you will be unable to extend class thread
as Java classes can only extend a single class.
• However, a class can implement more than one interface.
Implementing Runnable interface

• The following is our MyThread class created by implementing the


runnable interface.
class MyThread implements Runnable {
//... <thread body is mostly the same>
}
• Classes that implement Runnable are instantiated in a different way.
• Thread t1 = new Thread(new MyThread(1));
• Note that implementing an interface requires you to define all the
methods in the interface
• For the Runnable interface, you are required in your implementing
class to define the run() method or your program will not run.
Java Thread Example by implementing Runnable interface

class Multi3 implements Runnable{


public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi3 m1=new Multi3();
Thread t1 =new Thread(m1); // Using the constructor Thread(Runnable r)
t1.start();
}
}

Output: thread is running...


Using the Thread Class: Thread(String Name)
We can directly use the Thread class to spawn new threads using the constructors defined above.
public class MyThread1
{
// Main method
public static void main(String argvs[])
{
// creating an object of the Thread class using the constructor Thread(String name)
Thread t= new Thread("My first thread");
// the start() method moves the thread to the active state
t.start();
// getting the thread name by invoking the getName() method
String str = t.getName();
System.out.println(str);
}
}
Output: My first thread
Using the Thread Class: Thread(Runnable r, String name)
public class MyThread2 implements Runnable {
public void run() {
System.out.println("Now the thread is running ...");
}
public static void main(String argvs[]) {
Runnable r1 = new MyThread2();
// creating an object of the class Thread using Thread(Runnable r, String name)
Thread th1 = new Thread(r1, "My new thread");
// the start() method moves the thread to the active state
th1.start();
// getting the thread name by invoking the getName() method
String str = th1.getName();
System.out.println(str);
}
}
Output: My new thread
Now the thread is running
Basic Threads
Create a thread that simply prints out a number 500 times in a row.
class MyThread extends Thread
{ int i;
MyThread(int i) {
this.i = i;
}
public void run() {
for (int ctr=0; ctr < 500; ctr++) {
System.out.print(i);
}
}
}
Basic Threads….
To show the difference between parallel and non-parallel execution,
we have the following executable MyThreadDemo class
class MyThreadDemo {
public static void main(String args[]) {
MyThread t1 = new MyThread(1);
MyThread t2 = new MyThread(2);
MyThread t3 = new MyThread(3);
t1.run();
t2.run();
t3.run();
System.out.print("Main ends");
}
}
Basic Threads…
Upon executing MyThreadDemo, we get output that looks like this
java MyThreadDemo…..
1111111111...22222222.....33333......Main ends
As can be seen, our program first executed t1's run method, which prints 500
consecutive 1's.
After that t2's run method, which prints consecutive 2's, and so on.
Main ends appears at the last part of the output as it is the last part of the
program.
What happened was serial execution, no multithreaded execution occurred
This is because we simply called MyThread's run() method
Basic Threads….
• To start parallel execution, we call MyThread's start() method, which is built-in in
all thread objects.

class MyThreadDemo {
public static void main(String args[]) {
MyThread t1 = new MyThread(1);
MyThread t2 = new MyThread(2);
MyThread t3 = new MyThread(3);
t1.start();
t2.start();
t3.start();
System.out.print("Main ends");
}
}
Basic Threads

• When we run MyThreadDemo we can definitely see that


three run methods are executing at the same time
• java MyThreadDemo
• 111111111122331122321122333331111Main
ends111333222...
Basic Threads

• Note the appearance of the "Main ends" string in the middle of the
output sequence
• > java MyThreadDemo
• 111111111122331122321122333331111Main ends111333222...
• This indicates that the main method has already finished
executing while thread 1, thread 2 and thread 3 are still running.
• Running a main method creates a thread.
• Normally, your program ends when the main thread ends.
• However, creating and then running a thread's start method
creates a whole new thread that executes its run() method
independent of the main method.
Pausing Thread
• Threads can be paused by the sleep() method.
• For example, to have MyThread pause for half a second
before it prints the next number, we add the following lines of
code to our for loop.

for (int ctr=0; ctr < 500; ctr++) {


System.out.print(i); try {
Thread.sleep(500); // 500 miliseconds
} catch (InterruptedException e) { }
}

• Thread.sleep() is a static method of class thread and can be


invoked from any thread, including the main thread.
Pausing Thread
for (int ctr=0; ctr < 500; ctr++) {
System.out.print(i);
try {
Thread.sleep(500); // 500 miliseconds
} catch (InterruptedException e) { }
}

• The InterruptedException is an unchecked exeception that is thrown


by code that stops a thread from running.
• Unchecked exception causing lines must be enclosed in a try-catch, in this
case, Thread.sleep().
• An InterruptedException is thrown when a thread is waiting, sleeping,
or otherwise paused for a long time and another thread interrupts it
using the interrupt() method in class Thread.
Creating Multiple Threads
class NewThread implements Runnable {
String name; // name of thread
Thread t; This is the entry point for thread public void run() {
NewThread(String threadname) { try {
name = threadname; for(int i = 3; i > 0; i--){
t = new Thread(this, name); System.out.println(name + “: ” + i);
System.out.println("New thread: " + t); Thread.sleep(1000);
t.start(); // Start the thread }
} } catch (InterruptedException e){
System.out.println(name + “ interrupted”);
}
System.out.println(name + “ exiting”);
}
}
Creating Multiple Threads…..
class MultiThreadDemo {
public static void main(String args[]) {
new NewThread("One"); // start threads
new NewThread("Two");
new NewThread("Three");
try { // wait for other threads to end
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Creating Multiple Threads….output
If main thread to finish last. this is accomplished by calling sleep( ) within main( ),
with a long enough delay to ensure that all child threads terminate prior to the main
thread.
However, this is hardly a satisfactory solution, and it also raises a larger question:
How can one thread know when another thread has ended?

Thread provides 2 ways to determine whether a thread has finished.


First, you can call isAlive( ) on the thread. This method is defined by Thread, and
returns true if the thread upon which it is called is still running. It
returns false otherwise
final boolean isAlive( )

More commonly use method to wait for a thread to finish is join( ):


final void join( ) throws InterruptedException
This method waits until the thread on which it is called terminates.
Example:
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();
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");
}
New thread: Thread[One,5,main]
System.out.println("Thread One is alive: “+ ob1.t.isAlive());
New thread: Thread[Two,5,main]
System.out.println("Thread Two is alive: “+ ob2.t.isAlive()); New thread: Thread[Three,5,main]
System.out.println("Thread Three is alive: “+ ob3.t.isAlive()); Thread One is alive: true
System.out.println("Main thread exiting."); Thread Two is alive: true
Thread Three is alive: true
} Waiting for threads to finish.
} One: 5
Two: 5
Three: 5
One: 4
Two: 4
Three: 4
One: 3
Two: 3
Three: 3
One: 2
Two: 2
Three: 2
One: 1
Two: 1
Three: 1
Two exiting.
Three exiting.
One exiting.
Thread One is alive: false
Thread Two is alive: false
Thread Three is alive: false
Main thread exiting.
Thread Priority
• Thread priorities are used by the thread scheduler to decide when
each thread should be allowed to run.

• In theory, higher-priority threads get more CPU time than lower-


priority threads

• To set a thread’s priority, use the setPriority( ) method, which is a


member of Thread. This is its general form:
final void setPriority(int level)

• Here, level specifies the new priority setting for the calling thread.
The value of level must be within the range MIN_PRIORITY and
MAX_PRIORITY.
Thread Priority
• Currently, these values are 1 and 10, respectively.
• i.e. final variable MIN_PRIORITY set as 1 and
• final variable MAX_PRIORITY set as 10
• To return a thread to default priority, specify NORM_PRIORITY,
which is currently 5.
• These priorities are defined as static final variables within Thread.
• Method setPriority to set priority of thread
RunableObj.ThreadObj.setPriority (NORM_PRIORITY + 2)
• Method getPriority to obtain current priority of thrread
RunableObj.ThreadObj.getPriority() returns integer between 1 to 10
class A extends Thread{
public void run(){
for(int i=1;i<=5;i++)
System.out.println("\t From Thread A: i="+i);
System.out.println("threadid of A"+currentThread().getId());
System.out.println("thread Priority of A"+currentThread().getPriority());
System.out.println("Exit A");
}
}

class B extends Thread{


public void run(){
print();
for(int j=1;j<=5;j++)
System.out.println("\t From Thread B:j="+j);
System.out.println("Exit B");
}
}
class TestThread{
public static void main(String args[]){
A thA1=new A();
A thA2=new A();
B thB=new B();
System.out.println("threadid of A1 "+thA1.getId());
System.out.println("threadid of B "+thB.getId());
thB.setPriority(Thread.MAX_PRIORITY);
thA1.setPriority(thA2.getPriority()+1);
thA2.setPriority(Thread.MIN_PRIORITY);
System.out.println("Priority of A= "+thA1.getPriority());
System.out.println("thread Priority of B ="+thB.getPriority());
thA1.start();
thB.start();
thA2.start();
}
}
Thread Synchronization
• When we start two or more threads within a program, there may be a situation when
multiple threads try to access the same resource and finally they can produce
unforeseen result due to concurrency issues.
• For example, if multiple threads try to write within a same file then they may corrupt
the data because one of the threads can override data or while one thread is opening
the same file at the same time another thread might be closing the same file.
• So there is a need to synchronize the action of multiple threads and make sure that
only one thread can access the resource at a given point in time.
• Java programming language provides a very handy way of creating threads and
synchronizing their task by using synchronized blocks. You keep shared resources
within this block.
General form of the synchronized statement –
synchronized(objectidentifier) {
// Access shared variables and other shared resources
}
Thread Synchronization class ThreadDemo extends Thread {
private Thread t;
•Here, the objectidentifier is a reference to private String thName;
an object whose lock associates with the Print PD;
ThreadDemo( String name,Print pd) {
monitor that the synchronized statement
thName = name;
represents. PD = pd;
}
public void run() {
class Print{
PD.printCount();
public void printCount() {
System.out.println("Thread " + thName +
try { " exiting.");
for(int i = 5; i > 0; i--) { }
System.out.println("Counter--"+ i); public void start () {
} System.out.println("Starting " + thName );
} catch (Exception e) { if (t == null) {
System.out.println("Thread interrupted."); t = new Thread (this, thName);
} t.start ();
}
}
}
}
}
Thread Synchronization…
public class TestThread {
public static void main(String args[]) {
Print PD = new Print();
ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );
ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );
T1.start();
T2.start(); // wait for threads to end
try {
T1.join();
T2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
class ThreadDemo extends Thread {
Multithreading Example with private Thread t;
Synchronization private String thName;
Print PD;
ThreadDemo( String name,Print pd) {
class Print{ thName = name;
public void printCount() { PD = pd;
try { }
for(int i = 5; i > 0; i--) { public void run() {
System.out.println("Counter--"+ i); synchronized(PD) {
} PD.printCount();
} catch (Exception e) { }
System.out.println("Thread interrupted."); System.out.println("Thread " + thName + " exiting.");
} }
} public void start () {
} System.out.println("Starting " + thName );
if (t == null) {
t = new Thread (this, thName);
t.start ();
}
}
}
Multithreading Example with Synchronization
public class TestThread {
public static void main(String args[]) {
Print PD = new Print();
ThreadDemo T1 = new ThreadDemo( "Thread - 1 ", PD );
ThreadDemo T2 = new ThreadDemo( "Thread - 2 ", PD );
T1.start();
T2.start(); // wait for threads to end
try {
T1.join();
T2.join();
} catch ( Exception e) {
System.out.println("Interrupted");
}
}
}
Interthread communication
Inter-thread communication is important when you develop an application where
two or more threads exchange some information.
There are three simple methods and a little trick which makes thread
communication possible. All the three methods are listed below:
1. public void wait()
Causes the current thread to wait until another thread invokes the notify().
2. public void notify()
Wakes up a single thread that is waiting on this object's monitor.
3. public void notifyAll()
Wakes up all the threads that called wait( ) on the same object.
These methods have been implemented as final methods in Object, so they are
available in all the classes. All three methods can be called only from within
a synchronized context.
Examples shows how two threads can communicate using wait() and notify() method.
Class Chat{
boolean flag = false;
public synchronized void Question(String msg)
{
if (flag) {
try {
wait(); public synchronized void Answer(String msg) {
} catch (InterruptedException e) { if (!flag) {
e.printStackTrace(); try {
} wait();
} } catch (InterruptedException e) {
System.out.println(msg); e.printStackTrace();
flag = true; }
notify(); }
} System.out.println(msg);
flag = false;
notify();
}
}
Examples shows how two threads can communicate using wait() and notify() method.
class T1 implements Runnable {
Chat m;
String[] s1={ "Hi", "How are you ?", "I am also doing fine!" };
public T1(Chat m1) {
this.m=m1;
new Thread(this, "Question").start();
} class T2 implements Runnable {
public void run() { Chat m;
for (int i = 0; i < s1.length; i++) { String[] s2={ "Hi", "I am good, what about you?", "Great!"
m.Question(s1[i]); public T2(Chat m2) {
} this.m = m2;
} new Thread(this, "Answer").start();
} }
public void run() {
for (int i = 0; i < s2.length; i++) {
m.Answer(s2[i]);
}
}
}
Examples shows how two threads can communicate using wait() and notify() method.
public class TestThread {
public static void main(String[] args) {
Chat m=new Chat();
new T1(m);
new T2(m); Output
}
} Hi
Hi
How are you ?
I am good, what about you?
I am also doing fine!
Great!
Java - Thread Control
There are various static methods which you can use on thread objects to control
their behavior. Following table lists down those methods −
• public void suspend()
This method puts a thread in the suspended state and can be resumed using
resume() method.
• public void stop()
This method stops a thread completely.
• public void resume()
This method resumes a thread, which was suspended using suspend() method.
• public void wait()
Causes the current thread to wait until another thread invokes the notify().
• public void notify()
Wakes up a single thread that is waiting on this object's monitor.
Example
Class Demo implements Runnable {
public Thread t; catch (InterruptedException e) {
private String thName; System.out.println("Thread " + thName + " interrupte
boolean suspended = false; }
Demo( String name) { System.out.println("Thread " + thName + " exiting.");
thName = name; }
System.out.println("Creating " +thName );
}
public void run() {
System.out.println("Running " +thName );
try {
for(int i = 10; i > 0; i--) {
System.out.println("Thread:" + thName + "," + i);
Thread.sleep(300); // thread sleep for a while.
synchronized(this) {
while(suspended) {
wait(); }
}
}
}
public class TestThread {
Example public static void main(String args[]){
Demo R1 = new Demo( "Thread-1");
public void start () { R1.start();
System.out.println("Starting " + thName ); Demo R2 = new Demo( "Thread-2");
if (t == null) { R2.start();
t = new Thread (this, thName); try {
t.start (); Thread.sleep(1000);
} R1.suspend();
} System.out.println("Suspending First Thread");
void suspend() { Thread.sleep(1000);
suspended = true; R1.resume();
} System.out.println("Resuming First Thread");
synchronized void resume() { R2.suspend();
suspended = false; System.out.println("Suspending thread Two");
notify(); Thread.sleep(1000);
} R2.resume();
} System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
try {
System.out.println("Waiting for threads to finish.");
R1.t.join();
R2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}

Main thread exiting


Critical SectionProblem

• This section we will find out how to implement a solution to the


critical section problem using Java
• Recall that only a single process can enter its critical section,
all other processes would have to wait
• No context switching occurs inside a critical section
Critical SectionProblem

• Instead of printing a continuous stream of numbers, MyThread


calls a print10() method in a class MyPrinter
• print10() prints 10 continuous numbers on a single line before a
newline.
• Our goal is to have these 10 continuous numbers printed
without any context switches occuring.
• Our output should be:
...
1111111111
1111111111
2222222222
3333333333
1111111111
MyPrinter
We define a class MyPrinter that will have our print10() method

class MyPrinter {
public void print10(int value) {
for (int i = 0; i < 10; i++) {
System.out.print(value);
}
System.out.println(“ "); // newline after 10 numbers
}
}
MyPrinter
Instead of printing numbers directly, we use the print10() method in
MyThread, as shown by the following
class MyThread extends Thread {
int i;
MyPrinter p;
MyThread(int i) {
this.i = i;
p = new MyPrinter();
}
public void run() {
for (int ctr=0; ctr < 500; ctr++) {
p.print10(i);
}
}
}
• To achieve our goal there should not be any context switches
happening inside print10()
• Only a single thread should be allowed to execute inside print10()
• As can be seen, this is an example of the critical section
problem
• To solve this, we can use some of the techniques that
synchronize the code
Producer Consumer Problem
class Q{
int n;
boolean inStock=false;
synchronized void consumed(){
if (!inStock)
try{
wait();//tells the calling thread to give up the object q implicit moni and go to sleep until some other
thread that had object q's implicit moniter ,calls notify()
}
catch (InterruptedException e){ System.out.println("Caught ="+e);
}
System.out.println("Consumed="+n);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
System.out.println("SleepExp="+ e);
}
inStock=false;
notify();
}
synchronized void produced(int nth){
if (inStock)
try{
wait();
}catch (InterruptedException e){
System.out.println("Caught ="+e);
}
System.out.println("Produced="+nth);
n=nth++;
inStock=true;
try{
Thread.sleep(1000);// 1000millisec
}catch(InterruptedException e){
System.out.println("SleepExp="+ e);
}
notify();
}
}
class Consumer implements Runnable{
class Producer implements Runnable{
Q qElement; Q qElement;
Producer(Q q){ Consumer(Q q){
Thread t = new Thread(this,"Producer"); Thread t = new Thread(this,"Consumer");
qElement=q; t.start(); qElement=q;
} t.start();
public void run(){ }
int element=1;
public void run(){
while(true)
while(true)
qElement.produced(element++);
qElement.consumed();
} }
} class ProdCon{ }
public static void main(String args[]){
Q q=new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Cntl-C to stop");
}
}
output
Press Cntl-C to
stop Produced=1
Consumed=1
Press Cntl-C to
stop Produced=2
Consumed=2
Press Cntl-C to
stop Produced=3
Consumed=3
Press Cntl-C to
stop Produced=4
Consumed=4
Press Cntl-C to
stop Produced=5
Consumed=5
Press Cntl-C to
stop

You might also like