Multi threading
Threads A
program can be divided into a number of small processes. Each small
process can be addressed as a single thread.
process can be addressed as a single thread.
Multithreading
in java is a
process of executing multiple threads simultaneously.
In Java, the word thread means
two different things.
·
An instance of Thread class.
·
or, A thread of
execution.
Advantages of
Multi-threading in Java
1.
It allows multiple
operations at once, as they are not dependent on each other, thus not blocking
the user.
2.
It saves time as
multiple operations are possible.
3.
They are independent
thus making the functionality better.
Life cycle of threads
- New : A thread begins its life
cycle in the new state. It remains in this state until the start() method
is called on it.
- Runnable : After invocation of
start() method on new thread, the thread becomes runnable.
- Running : A thread is in running
state if the thread scheduler has selected it.
- Waiting : A thread is in waiting
state if it waits for another thread to perform a task. In this stage the
thread is still alive.
- Terminated : A thread enter the
terminated state when it complete its task.
Commonly used methods of Thread class:
1.
public void
run(): is used to perform action for a thread.
2.
public void
start(): starts the execution of the thread.JVM calls the run() method on
the thread.
3.
public void
sleep(long miliseconds): Causes the
currently executing thread to sleep (temporarily cease execution) for the
specified number of milliseconds.
4.
public void
join(): waits for a thread to die.
5.
public void
join(long miliseconds): waits for a thread
to die for the specified miliseconds.
6.
public int
getPriority(): returns the priority of the
thread.
7.
public int
setPriority(int priority): changes the
priority of the thread.
8.
public String
getName(): returns the name of the thread.
9.
public void
setName(String name): changes the name of
the thread.
10.
public Thread
currentThread(): returns the
reference of currently executing thread.
11.
public int
getId(): returns the id of the thread.
12.
public Thread.State
getState(): returns the state of the
thread.
13.
public boolean
isAlive(): tests if the thread is alive.
14.
public void
yield(): causes the currently executing thread object to temporarily
pause and allow other threads to execute.
15.
public void
suspend(): is used to suspend the thread(depricated).
16.
public void
resume(): is used to resume the suspended
thread(depricated).
17.
public void
stop(): is used to stop the thread(depricated).
|
Implementing the
Runnable Interface
The easiest way to create a thread is to create a class that
implements the runnable interface. After implementing runnable interface , the
class needs to implement the run() method, which is of form,
publicvoid
run()
·
run() method introduces a concurrent thread into your program.
This thread will end when run() method terminates.
·
You must specify the code that your thread will execute inside
run() method.
·
run() method can call other methods, can use other classes and
declare variables just like any other normal method.
class cse implements Runnable{
public void run(){
System.out.println("My thread is in running state.");
}
public static void main(String args[]){
cse obj=new cse();
Thread T1 =new Thread(obj);
T1.start();
}
}
Output
My thread is in running state.
Creating multi threads using extends
The procedure for creating threads based on extending the Thread
is as follows:
1. A class extending the Thread class overrides the run() method
from the Thread class to define the code executed by the thread.
2. This subclass may call a Thread constructor explicitly in its
constructors to initialize the thread, using the super() call.
3. The start() method inherited from the Thread class is invoked
on the object of the class to make the thread eligible for running.
Below is a program that illustrates instantiation and running of
threads by extending the Thread class instead of implementing the Runnable
interface. To start the thread you need to invoke the start()method on
your object.
class bkec extends Thread{
public void run(){
System.out.println("BKEC thread ");
}
public static void main(String args[]){
bkec t1=new bkec();
t1.start();
}
}
Thread class with sleep() method
class Test extends Thread
{
public void run(){
for(int i=1;i<5;i++){
try
{
Thread.sleep(500);
}catch(InterruptedException e)
{
System.out.println(e);
}
System.out.println(i);
}
}
public static void main(String args[]){
Test t1=new Test();
Test t2=new Test();
t1.start();
t2.start();
}
}
Output 1 2 2 3 3 4 4
Synchronization
At times when more than one thread try to access a shared
resource, we need to ensure that resource will be used by only one thread at a
time. The process by which this is achieved is called synchronization.
1)The synchronized keyword in Java
provides locking, which ensures mutually exclusive access to the shared
resource and prevents data race.
2) synchronized keyword also prevent reordering of code statement by the compiler which can cause a subtle concurrent issue if we don't use synchronized or volatile keyword.
3) synchronized keyword involve locking and unlocking. before entering into synchronized method or block thread needs to acquire the lock, at this point it reads data from main memory than cache and when it release the lock, it flushes write operation into main memory which eliminates memory inconsistency errors.
2) synchronized keyword also prevent reordering of code statement by the compiler which can cause a subtle concurrent issue if we don't use synchronized or volatile keyword.
3) synchronized keyword involve locking and unlocking. before entering into synchronized method or block thread needs to acquire the lock, at this point it reads data from main memory than cache and when it release the lock, it flushes write operation into main memory which eliminates memory inconsistency errors.
Synchronized method
Class Cse
{
Synchronized void show( string s)
{ system.out.println(“ hello “ +s);
Try{
Thread.sleep(500);
}
Catch(interruptedException e)
{ system.out.println(“end “+s);
}
}
Class bkec extends threads
{
Cse c;
Public bkec(cse c1, string s)
{
Super (s);
c =c1;
star();
}
}
Public void run( )
{
c.show(Thread.CurrentThread( ).getName( ));
}
}
Class bet
{
Public
static void main(string argc[])
{
Cse c1;
Bkec b=new
bkec(c1, “bkec”);
Bkec b1=new bkec(c1, “cse dept”);
Bkec b2=new bkec(c1, “bet trust”);
}
}
Output
Hello bkec
End bkec
Hello cse dept
End cse dept
Hello bet trust
End bet trust
Synchronized block
Class Cse
{
void
show( string s)
{ system.out.println(“ hello “ +s);
Try{
Thread.sleep(500);
}
Catch(interruptedException e)
{ system.out.println(“end “+s);
}
}
Class bkec extends threads
{
Cse c;
Public bkec(cse c1, string s)
{
Super (s);
c =c1;
star();
}
}
Public void run( )
{
Synchronized(c)
{
c.show(Thread.CurrentThread( ).getName( ));
}
}
Class bet
{
Public
static void main(string argc[])
{
Cse c1;
Bkec b=new
bkec(c1, “bkec”);
Bkec b1=new bkec(c1, “cse dept”);
Bkec b2=new bkec(c1, “bet trust”);
}
}
Output
Hello bkec
End bkec
Hello cse dept
End cse dept
Hello bet trust
End bet trust
Producer-Consumer
solution using threads in Java
In computing,
the producer–consumer problem (also known as the bounded-buffer problem) is a
classic example of a multi-process synchronization problem. The problem
describes two processes, the producer and the consumer, which share a common,
fixed-size buffer used as a queue.
§ The producer’s job is to generate data, put it into the buffer,
and start again.
§ At the same time, the consumer is consuming the data (i.e.
removing it from the buffer), one piece at a time.
Problem
To make sure that the producer won’t try to add data into the buffer if it’s full and that the consumer won’t try to remove data from an empty buffer.
To make sure that the producer won’t try to add data into the buffer if it’s full and that the consumer won’t try to remove data from an empty buffer.
Solution
The producer is to either go to sleep or discard data if the buffer is full. The next time the consumer removes an item from the buffer, it notifies the producer, who starts to fill the buffer again. In the same way, the consumer can go to sleep if it finds the buffer to be empty. The next time the producer puts data into the buffer, it wakes up the sleeping consumer.
An inadequate solution could result in a deadlock where both processes are waiting to be awakened.
The producer is to either go to sleep or discard data if the buffer is full. The next time the consumer removes an item from the buffer, it notifies the producer, who starts to fill the buffer again. In the same way, the consumer can go to sleep if it finds the buffer to be empty. The next time the producer puts data into the buffer, it wakes up the sleeping consumer.
An inadequate solution could result in a deadlock where both processes are waiting to be awakened.
The Producer/Consumer Example
In this example, the
Producer
generates an integer between 0 and 9 (inclusive), stores it
in a CubbyHole
object. To make the synchronization problem more
interesting, the Producer
sleeps
for a random amount of time between 0 and 100 milliseconds before repeating the
number-generating cycle:public class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(number, i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
The
Consumer
consumes all integers from the CubbyHole
(the exact
same object into which the Producer
put
the integers in the first place) as quickly as they become available.public class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get(number);
}
}
}
Bounded Buffer
Problem
Bounded buffer problem, which is also called producer
consumer problem, is one of the classic problems of synchronization. Let's
start by understanding the problem here, before moving on to the solution and
program code.
What is the Problem
Statement?
There is a buffer of
n
slots and each slot is capable of storing one unit of data.
There are two processes running, namely, producer and consumer,
which are operating on the buffer.
Bounded Buffer Problem
A producer tries to insert data into an empty slot of the buffer.
A consumer tries to remove data from a filled slot in the buffer. As you might
have guessed by now, those two processes won't produce the expected output if
they are being executed concurrently.
There needs to be a way to make the producer and consumer work in
an independent manner.
Here's a Solution
One solution of this problem is to use semaphores. The semaphores
which will be used here are:
·
m
, a binary semaphore which is used to acquire and
release the lock.
·
empty
, a counting semaphore whose initial value is the
number of slots in the buffer, since, initially all slots are empty.
·
full
, a counting semaphore whose initial value
is 0
.
At any instant, the current value of empty represents the number
of empty slots in the buffer and full represents the number of occupied slots
in the buffer.
Next TopicsException Handling
Package
Interface
Applet
1 comment:
c programming create an image samples
Create a negative from png image
Post a Comment