Professional Documents
Culture Documents
creates
myThread = new Thread() Thread myThread
myThread.start(); start();
run{ }
The Thread class itself implements the Runnable interface;
it has its own run() method we can override to make it do something
useful:
class Animation extends Thread {
... public void run() class Thread implements Runnable
{ ……
}
}
class Animation extends Thread
Animation bouncy = new
Animation("Bouncy"); start( )
bouncy.start(); run{ }
A Thread's Life
A Thread continues to execute until one of the following things happens:
•It returns from its target run() method
•It's interrupted by an uncaught exception
•Its stop() method is called
So what happens if the run() method for a thread never terminates,
and the application that started the thread never calls its stop() method?
The answer is that the thread lives on, even after the application that
created it has finished.
In many cases, what we really want is to create background threads
that do simple, periodic tasks in an application.
The setDaemon() method can be used to mark a Thread as a daemon
thread that should be killed and discarded when no other application
threads remain.
Normally, the Java interpreter continues to run until all threads have
completed.
But when daemon threads are the only threads still alive, the
interpreter will exit.
class CountThread extends Thread{
main
int from ,to;
public CountThread(int f,int t){ 0..9 10..19 20..29
from = f; to = t;
}
public void run(){
for(int i=from;i<to;i++)
System.out.println("i = " + i);
}
public static void main(String args[]){
for(int i=0;i<3;i++) {
CountThread t = new CountThread (i*10,(i+1)*10);
t.start();
} } }
Thread States
• When a Thread is first created, it is in the NEW State
• When you invoke start method, the thread changes to
RUNNABLE state ( eligible for execution )
• When certain events happen to a RUNNABLE thread, it may
enter the NOT RUNNABLE state. When a thread is NOT
RUNNABLE, it is still alive, but it is not eligible for
execution.
• A NOT RUNNABLE thread becomes RUNNABLE again
when the condition that caused the thread to become NOT
RUNNABLE ends
• When a thread terminates, it is said to be DEAD
Thread States
NEW
start( )
resume( )/ notify( ) / sleep
timeout IO Finished NOT RUNNABLE
RUNNABLE /BLOCKED
suspend( )/ wait()/
sleep() / IO BLOCKED
run( ) ends
stop( ) DEAD
Thread – Control Methods
start() Used to start the execution the thread
stop() Deprecated. Used to stop the execution of the
thread no matter what the thread is doing
suspend() Deprecated. Used to temporarily stop the
execution of the thread.
resume() Deprecated. Used to resume the execution of a
suspended thread.
sleep(long millisec) A class method that causes the Java
Runtime to put the Caller thread to sleep. The
InterruptedException, may be thrown.
join() Used for the caller’s thread to wait for this thread to
die.
yield( ) It is used to make sure other threads have the
chance to run.
Thread Information
currentThread( ) Return’s the Caller Thread
isAlive( ) Return’s true if the Thread is started but not dead yet.
system
Reference MAIN
gc
Handler
main MyGroup
T1 T2 T3
public class TInfo{
public static void main(String args[ ]){
ThreadGroup root,parent; root=
Thread.currentThread( ).getThreadGroup(); root.list();
parent = root.getParent(); parent.list();
} }
java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
java.lang.ThreadGroup[name=system,maxpri=10]
Thread[Reference Handler,10,system]
Thread[Finalizer,8,system]
Thread[Signal Dispatcher,10,system]
java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
Examples
class WithoutThread{
public static void main(String args[]){
NoThread p = new NoThread();
p.run(); show("Another task starts");
}
static long basetime = System.currentTimeMillis();
static void show(String msg)
{
long elapsedtime = System.currentTimeMillis()- basetime;
System.out.println(msg + " at " + (elapsedtime/1000.0) + "
seconds");
}
}
class NoThread // not a thread
{ NoThread()
{ WithoutThread.show("Nothread created");
}
public void run()
{ WithoutThread.show("Nothread started");
try{
Thread.sleep(10000);
}
catch(InterruptedException e){ }
WithoutThread.show("Nothread finishes");
}
}
Modify it to Thread
class WithThread
{ public static void main(String args[])
{ Threaded p = new Threaded();
p.start();
show("Another task starts");
}
static long basetime = System.currentTimeMillis();
static void show(String msg)
{
long elapsedtime = System.currentTimeMillis()- basetime;
System.out.println(msg + " at " + (elapsedtime/1000.0) + " seconds");
}}
class Threaded extends Thread
{ Threaded()
{
WithThread.show("Nothread created");
}
public void run()
{ WithThread.show("Nothread started");
try{ Thread.sleep(10000);
}
catch(InterruptedException e){}
WithThread.show("Nothread finishes");
}}
Thread Methods
public class JoinTest {
public static void main(String args[]) {
FirstThread first = new FirstThread();
SecondThread second = new SecondThread(); first.start();
second.start(); try
{ first.join();
second.join();
}catch(InterruptedException e) { }
System.out.println("Main thread will end..");
}
}
class FirstThread extends Thread {
public void run(){
try{ System.out.println("First thread starts running..");
sleep(1000);
System.out.println("First thread finishes running..");
}catch(InterruptedException e){}
}}
class SecondThread extends Thread {
public void run(){
try{ System.out.println("Second thread starts running..");
sleep(2000);
System.out.println("Second thread finishes running..");
}catch(InterruptedException e){}} }
setDaemon( true)
class FirstThread extends Thread
{
FirstThread () { setDaemon(true); }
…….
Method 2
Method 3
Examples on Synchronization
INTER THREAD COMMUNICATION
If data is produced by one thread and consumed by another
thread. The consumer has to check every now and then whether it
has to data to act upon.
This is a huge waste of CPU time.
The only modification to make in the Producer code is to change the call
to notify() in putMessage() to a call to notifyAll().
Here is some sample output when there are two consumers running, as
in the main() method shown above:
One got message: Wed Mar 20 20:00:01 CST 1996
Two got message: Wed Mar 20 20:00:02 CST 1996
One got message: Wed Mar 20 20:00:03 CST 1996
Two got message: Wed Mar 20 20:00:04 CST 1996
……
Reentrant locks are important because they eliminate the
possibility of a single thread's deadlocking itself on a lock that it
already holds.
Consider this class:
public class Reentrant {
public synchronized void a() {
b();
System.out.println("here I am, in a()");
}
public synchronized void b()
{ System.out.println("here I am, in b()");
}
}
Reentrant contains two synchronized methods: a and b.
The first, a, calls the other, b. When control enters method a, the
current thread acquires the lock for the Reentrant object.
Now a calls b; because b is also synchronized, the thread
attempts to acquire the same lock again.
Because the Java platform supports reentrant locks, this works.
In platforms that don't support reentrant locks, this sequence of
method calls causes deadlock.
The current thread can acquire the Reentrant object's lock again,
and both a and b execute to conclusion, as is evidenced by the
output:
here I am, in b()
here I am, in a()