Threads

advertisement

For implementing threads do one of the following
Extend from Thread class
Or
Implement Runnable interface

Sample program #1
Public class MyThread extends Thread
{
Public MyThread()
{
}
Public void run()
{
}
}Thread class
Public class client
{
Main()
{
MyThread obj=new MyThread()
Obj.start(); // start() will call the run() method
}//end main()
}//client class
 Sample program #2
public class thread6 implements Runnable
{
int sum;
Thread t;
public thread6(int sum)
{
this.sum=sum;
t=new Thread(this);
t.start();
}
public void run()
{
sum++;
}
}
//Launch 100 threads each thread add 1 to a variable sum
public class client6
{
public static void main(String args[]) throws InterruptedException
{
int sum=0;
for(int i=0;i<100;i++)
{
new thread6(sum++);
}
System.out.println("sum="+sum);
}
}



Use wait() instead of suspend() to suspend a thread,
Use notify() instead of resume() of resume a thread,
Suspend() and resume() are known to be deadlock prone.

The main thread should start first and should finish last, else the java program
might hang.

Sleep() method allows execution to switch to another thread. This might result in
race conditions if the methods are not synchronized and the other threads are
also calling the same methods.

Synchronized void call(string msg)  The word synchronized serializes access
to that method, i.e. when one thread is calling a method then the state of all other
threads is saved in a file.ser and this particular method is locked for use by the
current thread executing on it.
So by call to synchrinzed the current method will execute completely even if it
has a sleep method inside it .
Consider the following code:Public void call()
{
System.out.println(“[hello”);
Sleep(2000);
System.out.println(“]”);
}
The above method is not synchronized will print something like
[hello[hello[hello…]
This is because when sleep(2000) is called, then the control is passed to some
other thread. i.e. the complete call() method is not called at once
Consider the following synchronized code
public synchronized void call()
{
System.out.println(“[hello”);
Sleep(2000);
System.out.println(“]”);
}
Herein the output will be
[hello][hello][hello]…
This is because the complete call() method is executed along with the sleep()
method and then the control is transferred to some other thread.

Synchronized block
Public void run()
{
Thread obj_name=new Thread();
Synchronized (obj_name)
{
Obj_name.call();
}
}
Method
Boolean isAlive()
Final void join() throws
InterruptedException
Sleep()
wait()
Use
Is the current thread alive
This method waits until the
thread on which it is called
is terminated.
Sleep() method allows
execution to switch to
another thread. This might
result in race conditions if
the methods are not
synchronized and the other
threads are also calling the
same methods
Tells the calling thread to
give up the monitor and go
to sleep until some other
comments
Used in inter-thread process
communication
notify()
notifyAll()
thread enters the same
monitor and calls notify()
Wakes up the first thread
that called wait() on the
same object.
Wakes up all the threads
that called wait() on the
same object. The highest
priority thread will run first.
Used in inter-thread process
communication
Used in inter-thread process
communication
Threads
1)
Process
Threads
In a multitasking operating system, each A thread shares the address space of
program is run as a separate process
the the program that created it
Process switching has overhead
minimal overhead with thread switching
2) Difference between Runnable (interface) and Thread (class) syntax
Thread
Runnable
Thread class
Runnable interface
public class thread1 extends Thread
public class runnableThread2
{
implements Runnable
private String name;
{
public thread1(String name)
private String name;
{
public runnableThread2(String name)
this.name=name;
{
}
this.name=name;
}
public void run()
{
public void run()
for(int i=0;i<5;i++)
{
{
for(int i=0;i<5;i++)
System.out.println("Thread name -{
>"+this.name);
System.out.println("Thread name -}
>"+this.name);
}
}
}
}
}
Main Thread
public class mainThread1 {
public static void main(String[] args) {
thread1 t1=new thread1("ankur");
thread1 t2=new thread1("sandeep");
thread1 t3=new thread1("aditya");
t1.start();
t2.start();
t3.start();
}
Main Thread
public class mainThread2 {
public static void main(String[] args) {
runnableThread2 mt1=new
runnableThread2("ankur");
runnableThread2 mt2=new
runnableThread2("sandeep");
runnableThread2 mt3=new
runnableThread2("priya");
}
//Here the arguement to Thread class
should be a Runnble object only, not
even a Thread
// class object will do.
Thread t1=new Thread(mt1);
Thread t2=new Thread(mt2);
Thread t3=new Thread(mt3);
t1.start();
t2.start();
t3.start();
// The blue portion indicate the difference block in creating threads from either
extending from the Thread class or implementing from the Runnable interface.
3) Thread.yield()

Use yield to prevent a thread from hogging the CPU
public void run() {
for (int i=0; i<8; i++) {
System.out.println(internalName);
Thread.yield();
}
}
4) Thread.join()
5) Synchronized block


Synchronized methods or code blocks LOCK an object
Synchronization permits multiple threads to act concurrently without interfering
with each other.
 any object may serve as the lock object
eg. 1
public static void abs (int[ ] values) {
synchronized (values) {
for (int i=0; i<values.length; i++) {
if (values[i] < 0)
values[i] = -values[i];
}
}
}
Eg.2
synchronized (<some object>) {
statements;
} some object to lock

Variables cannot be synchronized.
However you can control access if you:
– declare variables private
– provide accessor(getter and setter) methods.

Synchronized and Non-Synchronized thread locking
Synchronized objects can be accessed by threads only if it is not locked by any other
thread, a non-synchronized thread can be accessed by more than one threads
1) There is atleast one thread always active in a program, this is the main thread.
2) There is one call stack maintained per thread. The main is the first method on
the stack .As soon as we create a new thread, a new stack materializes and
methods called from that thread run in a call stack that’s separate from the
main() call stack.
3) The new call stack always is created when the run() method starts executing.
4) We can define and instantiate a thread in one of the following two ways.
Method1: By extending the Thread class
Public class MyThread extends Thread
{
Public static void main(String args[])
{
MyThread t=new MyThread();
t.start();
}
Public void run()
{
//do something
}
Method2: By implementing the Runnable interface.
Public class MyThread
{
Public static void main(String args[])
{
MyRunnable r=new MyRunnable();
Thread t1=new Thread1(r);
Thread t2=new Thread1(r);
Thread t3=new Thread1(r);
T1.start();
T2.start();
T3.start();
}
}
Public class MyRunnable implements Runnable
{
Public void run()
{
//do something
}
}
5) Calling a run() method directly just means you are invoking a method from
whatever thread is currently executing, and the run() method goes onto the
current call stack rather than at the beginning of a new call stack. The
following code does not start a new thread of execution.
Runnable r=new Runnable();
r.run();
6) When to use a thread class and when to use a Runnable interface
a. Extending the Thread class is the easiest but it is not a good OOPs
practice, because we cannot extend any other class if we extend the
Thread class because java supports MultiLevel inheritance for classes
and Muliple inheritance for interfaces. So if we implement the
Runnable interface instead of a Thread class for our class then we can
implement any no of interfaces and a class also.
b. The only time it makes sense to extend the Thread class is when, we
have a more specialized version of the Thread class.
7) to print the name of the currently executing thread
Thread.currentThread().getName();
To set the name of the currently executing thread
Public class NameThread
{
Public static void main(String args[])
{
NameRunnable nr=new NameRunnable();
Thread t=new Thread(nr);
t.setName(“FirstThread”);
}
}
8) Thread states
a. New: The thread instance has been instantiated, but the start() method
has not been invoked on the thread.
b. Dead: When a thread completes its run() method, the thread ceases to
be a thread of execution.
Once a thread is dead it can never be restarted.
c. Runnable: This is the state a thread is eligible to run(is in the Runnable
pool) but the scheduler has not selected it to be in the running thread..
A thread first enters the runnable state when the start() method is
invoked.
When a thread is in the runnable state(in the Runnable pool) it is
considered alive.
The order in which runnable threads are chosen to run is not
guaranteed.
All threads in the Runnable state could be said to be in a pool, and any
of them could be chosen to be executed, because which thread is
selected from the Runnable pool of threads is dependent on the
scheduler(OS part) and the JVM.
d. Waiting / Blocked / Sleeping: The thread is alive but is currently not
eligible to run. Although the thread is alive, it is not in the Runnable
pool because it is waiting for some I/O resource or is sleeping(sleep()
method called on the thread) or it is waiting(wait() method called on
the thread).
Some other waiting methods on the thread, namely resume(),
suspend(), and stop() have been deprecated.
e. Running:This is when the scheduler selects the thread from the
Runnable pool to be the currently executing process.
9) Sleep(milliseconds)
Sleeps the thread for said no of milliseconds.
When a thread’s sleep expires and it wakes up it does not mean it will go to
Running state, it only goes to the Runnable state.
So the time specified in sleep() is the minimum duration in which the thread
wont run, but it is not the exact duration in which the thread wont run.
10) Yield
Yield() makes the currently running thread head back to runnable state to
allow other threads of the same priority to get their turn.
e.g.
Thread.yield().  Will cause the currently executing thread to give up
Running state and go to Runnable state.
11) Join
It is a non static method.
Lets one thread join onto the end of another thread.
Imagine the following scenario. You are preparing for tomorrow's final examine and feel
a little hungry. So, you give your younger brother ten bucks and ask him to buy a pizza
for you. In this case, you are the main thread and your brother is a child thread. Once
your order is given, both you and your brother are doing their job concurrently (i.e.,
studying and buying a pizza). Now, we have two cases to consider. First, your brother
brings your pizza back and terminates while you are studying. In this case, you can stop
studying and enjoy the pizza. Second, you finish your study early and sleep (i.e., your
assigned job for today - study for tomorrow's final exam - is done) before the pizza is
available. Of course, you cannot sleep; otherwise, you won't have a chance to eat the
pizza. What you are going to do is to wait until your brother brings the pizza back. This is
exactly the problem and solution we mentioned at the end of the previous section.
Thread join is designed to solve this problem. A thread can execute a thread join to wait
until the other thread terminates. In our case, you - the main thread - should execute a
thread join waiting for your brother - a child thread - to terminate. In general, thread
join is for a parent to join with one of its child threads. Thread join has the
following activities, assuming that a parent thread P wants to join with one of its child
threads C.


When P executes a thread join in order to join with C, which is still running, P is
suspended until C terminates. Once C terminates, P resumes.
When P executes a thread join and C has already terminated, P continues as if no
such thread join has ever executed (i.e., join has no effect).
A parent thread may join with many child threads created by the parent. Or, a
parent only join with some of its child threads, and ignore other child threads.
In this case, those child threads that are ignored by the parent will be
terminated when the parent terminates.
12) Thread Priorities
Thread Priorities are between 1 and 10 with 10 being the highest. So the
currently running thread has a priority equal than or greater than the highest
priority thread in the Runnable pool of threads.
e.g.
FooRunnable r=new FooRunnable();
Thread t=new Thread(r);
t.setPriority(8);
t.start();
The JVM will never change the priority of a thread.
The default priority is 5.
Thread.MIN_PRIORITY (1)
Thread.NORM_PRIORITY(5)
Thread.MAX_PRIORITY(10)
13) Thread Groups
14) notify() / notifyAll()and wait
If threads want to communicate about the status of their locks then they can do so
with the three methods of the java.lang.Object class namely notify, notifyAll and
wait.
These methods can only be called from within a synchronized context.
A thread cant invoke a wait or notify method on an object unless it owns that
objects lock.
//Without wait and notify
public class ThreadA {
public static void main(String args[])
{
ThreadB b=new ThreadB();
b.start();
synchronized(b)
{
try
{
System.out.println("waiting for thread b to
complete...");
//b.wait();
System.out.println("after b");
}
catch(Exception e){
}
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this){
for(int i=0;i<10;i++)
{
total+=i;
System.out.println(total);
}
//
notify();
}
}
}
Output:
waiting for thread b to complete...
after b
0
1
3
6
10
15
21
28
36
45
//With notify and wait()
public class ThreadA {
public static void main(String args[])
{
ThreadB b=new ThreadB();
b.start();
synchronized(b)
{
try
{
System.out.println("waiting for thread b to
complete...");
b.wait();
System.out.println("after b");
}
catch(InterruptedException e){
}
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this){
for(int i=0;i<10;i++)
{
total+=i;
System.out.println(total);
}
notify();
}
}
}
Output
waiting for thread b to complete...
0
1
3
6
10
15
21
28
36
45
after b
15) Synchronize
Only methods can be synchronized, not variables
Each object has just one lock, each thread however can have more than one
lock e.g a thread can enter a synchronized method, thus acquiring a lock and
then immediately invoke a synchronized method on a different object thus
acquiring that lock as well. As the stack unweilds the lock on the top of the
stack is released first.
A class have have synchronized and unsynchronized methods.
 if two methods are synchronized in a class only one thread can be
accessing one of the two methods. In other words once a thread acquires the
lock on an object no other thread can enter any of the synchronized methods
in that class(for that object).
If a class has both synchronized and non-synchronized methods, multiple
threads can still access the non-synchronized methods of the class.
 if a thread goes to sleep , it takes its locks with it.
you can synchronize a block of code rather than a method. Synchronization
does hurt concurrency. We don’t want to synchronize any more code than is
necessary to protect your data.
e.g.
class syncTest
{
Public void doStuff()
{
System.out.println(“not synchronized”);
Synchronized(this);
System.out.println(“synchronized”);
}
}
}
When you synchronize a method, the object used to make the method call is
the object whose lock must be acquired.
In case of a synchronized block, we have to specify which objects lock you
want to use as a lock. This gives us the ability to have more than one lock for
code synchronization within a single object.
e.g.
void someOperation(Foo foo) {
int sum = 0;
synchronized(foo) { // acquire foo lock
sum += foo.value;
}
// release foo lock
Download