0% found this document useful (0 votes)
26 views8 pages

Java Threading Basics Explained

The document describes threads in Java. A thread is a flow of execution within a process that allows a program to be divided into concurrent parts. Threads can be created by extending the Thread class or implementing the Runnable interface. A thread goes through different states such as new, runnable, not runnable, and dead. Threads can be assigned priorities to determine the order of execution. Finally, threads need synchronization mechanisms to safely share resources.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views8 pages

Java Threading Basics Explained

The document describes threads in Java. A thread is a flow of execution within a process that allows a program to be divided into concurrent parts. Threads can be created by extending the Thread class or implementing the Runnable interface. A thread goes through different states such as new, runnable, not runnable, and dead. Threads can be assigned priorities to determine the order of execution. Finally, threads need synchronization mechanisms to safely share resources.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1 THREADS IN JAVA

1.1 WHAT IS A THREAD

The Java Virtual Machine (JVM) is a multithreaded system. That is to say, it is capable of executing several
threads executing simultaneously. The JVM manages all the details, time allocation
execution, priorities, etc., in a manner similar to how an Operating System manages
multiple processes. The basic difference between an Operating System process and a Thread
Java is that threads run within the JVM, which is a process of the Operating System and therefore
they all share resources, including memory and the variables and objects defined there.
This type of processes where resources are shared are sometimes called lightweight processes.
(lightweight process).

Java supports the concept of Thread from the language itself, with some classes and
interfaces defined in the package [Link] and with specific methods for manipulation
Unthread the classObject.

From the perspective of applications, threads are useful because they allow the flow of
the program is divided into two or more parts, each responsible for a specific task in a way
independent. For example, one thread can handle communication with the user,
while others act in the background, transmitting a file,
accessing system resources (loading sounds, reading files ...), etc. In fact, all the
Programs with graphical interface (AWToSwing) are multithreaded because events and routines of
drawn from the windows runs on a thread different from the main one.

1.2 THE THREAD CLASS

The most direct way to create a multithreading program is to extend the Thread class and redefine
the method run(). This method is invoked when the thread is started (through a call to
start() method of the Thread class). The thread is started with the call to the run() method and
it ends when this one ends. The example illustrates these ideas:

public class ThreadExample extends Thread {


publicThreadExample(String str) {
super(str);
}
public void run() {
for(int i = 0; i < 10; i++)
[Link](i + " " + getName());
[Link]("Ends thread " + getName());
}
public static void main(String[] args) {
newThreadExample("Pepe").start();
newThreadExample("Juan").start();
[Link]("Ends main thread");
}
}

If the program is compiled and executed, an output like the following can be obtained:

End main thread

DistributedSystems::Threads in Java EUI-SG/[Link] 1


0 Pepe
1 Pepe
2 Pepe
3 Pepe
0 Juan
4 Pepe
1 John
5 Pepe
2 John
6 Pepe
3 John
7 Pepe
4 Juan
8 Pepe
5 Juan
9 Pepe
6 Juan
End thread Pepe
7 Juan
8 Juan
9 Juan
Finish the thread Juan

Running the program several times will show that it does not always run the same way.

Notes on the program:

• The Thread class is in the [Link] package. Therefore, the import is not necessary.
• The constructor public Thread(String str) takes a parameter that is the
identification of the Thread.
• The method run() contains the execution block of the Thread. Inside it, the method
getName()returnsthenameoftheThread(theonethathasbeenpassedasanargumenttothe
constructor).
• The method creates two objects of class Thread and starts them with the call
to the method start() (which starts the new thread and calls the method run()).
• Note the first completion message of the main thread in the output.
the execution of the threads is asynchronous. Once the call to the start() method is made, it
Returns control and continues its execution, independent of the other threads.
• In the output, the messages from one thread and another become mixed. The virtual machine assigns
times for each thread.

1.3. THE RUNNABLE INTERFACE

The Runnable interface provides an alternative method to using the Thread class.
for cases where it is not possible to make the defined class extend the Thread class.
This occurs when the class that is to be executed in a separate thread must extend
any other class. Since multiple inheritance does not exist, the cited class cannot extend to the
See the class 'Thready' again. In this case, the class must implement the Runnable interface.
slightly varying the way in which new threads are created and started.

The following example is equivalent to the previous section, but using the interface
Runnable:

Distributed Systems::Threads in Java EUI-SG/[Link] 2


public class Thread Example implements Runnable {
public void run() {
for(int i = 0; i < 5; i++)
[Link](i + " ");
[Link]().getName());
[Link]("Ends thread " +
[Link]().getName());
}
public static void main (String [] args) {
newThread(newThreadExample(), "Pepe").start();
newThread(newThreadExample(), "Juan").start();
Ends main thread
}
}

Note in this case:

• The Runnable interface is implemented instead of extending the Thread class.


• The builder that was there before is not necessary.
• In the main observe how the thread is created. That expression is equivalent
a:

ThreadExample example = new ThreadExample();


Thread thread = new Thread(example, "Pepe");
[Link]();

o First, we create the instance of our class.


o Then an instance of the Thread class is created, passing as parameters the
reference of our object and the name of the new thread.
o Lastly, the start method of the thread class is called. This method will start the
new thread and will call the method run() of our class.
• Finally, observe the call to the method getName() from run().getName is a
Thread class method, so our class must obtain a reference to
own thread. It is what the static method currentThread() of the class does
Thread.

1.4. THE LIFE CYCLE OF A THREAD

The graph summarizes the life cycle of a thread:

DistributedSystems::Threads in Java EUI-SG/[Link] 3


When the Thread class (or a subclass) is instantiated, a new Thread is created that is in
its initial state ('New Thread' in the chart). In this state, it is simply another object.
The thread is not yet running. The only method that can be invoked on it is the
methodstart().

When the start() method is invoked on the thread, the system creates the necessary resources, it
plan (assign priority) and call the method run(). At this moment the thread is running,
it is in the 'runnable' state.

If the method run() internally invokes the methods sleep() or wait() or the thread has to
waiting for an input/output operation, then the thread goes to the 'not runnable' state
(no executable) until the wait condition is completed. During this time the system may
give control to other active threads.

Finally, when the method finishes, the thread ends and enters the 'Dead' state.

2 THREADS AND PRIORITIES

Although a program uses multiple threads and they apparently run simultaneously,
el sistema ejecuta una única instrucción cada vez (esto es particularmente cierto en sistemas
with a single CPU), although the instructions are executed concurrently (interleaving
these are). The mechanism by which a system controls the concurrent execution of processes.
it is called scheduling. Java supports a simple mechanism called
fixed priority scheduling. This means that the scheduling of
the threads are executed based on the relative priority of a thread compared to the priorities of others.

The priority of a thread is an integer value (the higher the number, the higher the priority),
what can be assigned with the method setPriority. By default, the priority of a thread is equal
to the thread that created it. When there are several threads ready to be executed (state
(runnable), the virtual machine chooses the thread with the highest priority, which will be executed.
until

• A thread with a higher priority is in a position to be executed (runnable), or


• The thread ends (ends its methordun), or
• It stops voluntarily, or
• Some condition makes the thread not executable (runnable), like an operation.
input/output or, if the operating system has time division scheduling
(time slicing), when the allocated time expires.

If two or more threads are ready to execute and have the same priority, the virtual machine
it is yielding control in a cyclic manner (round-robin).

The fact that a thread with a higher priority interrupts another is called
preemptive scheduling

When a thread starts executing and does not voluntarily relinquish control so that it can
to run other threads, it is said to be a selfish thread. Some systems
Operating systems, like Windows, combat these attitudes with a planning strategy by
time division (time-slicing), which operates with threads of equal priority that compete for the

DistributedSystems::Threads in Java EUI-SG/[Link] 4


CPU. Under these conditions, the Operating System allocates time to each thread and relinquishes the
continually control all those competing for control of the CPU, preventing that
one of them appropriates the system for an extended period of time.

This mechanism is provided by the operating system, not Java.

3 THREADS SYNCHRONIZATION

The previous examples show how a program executes several threads asynchronously.
That is, once started, each thread lives independently of the others, there is no
no relationship between them, nor any conflict, since they share nothing. Without
embargo, there are occasions when different threads in a program do need to establish some
relationship with each other, or sharing objects. It is then necessary to have some mechanism that allows
synchronize threads, as well as, establish some 'rules of the game' for accessing resources (objects)
shared.

A typical example where two processes need to synchronize is the case when a thread
produce some kind of information that is processed by another thread. The first thread is given...
we will call the first one producer and the second one consumer. The producer could have the following
aspect:

public classProductorextendsThread {
privateContainer container;

publicProducer (Container c) {
container = c;
}

public void run() {


for(int i = 0; i < 10; i++) {
[Link](i);
[Link]("Producer. put: " + i);
try{
sleep((int)([Link]() * 100));
}catch(InterruptedException e) { }
}
}
}

Product has a member variable: container is a reference to an object.


Container, which is used to store the data that is being produced. The method generates
randomly the data and places it in the container with the put method. Then waits for a
random amount of time (up to 100 milliseconds) with the sleep method. The producer does not
it cares about whether the data has already been consumed or not. It simply places it in the container.

The consumer, for their part, could have the following aspect:

public class Consumer extends Thread {


privateContainer container;
publicConsumer (Container c) {

DistributedSystems::Threads in Java EUI-SG/[Link] 5


container= c;
}
public void run() {
intvalue = 0;
for (inti = 0; i < 10; i++) {
value = [Link]();
[Link]("Consumer. get: " + value);
}
}
}

The constructor is equivalent to that of the Producer. The method simply retrieves the data.
The container with the method gets displayed in the console. Neither does the consumer.
worry about whether the data is already available in the container or not.

Product consumers would use it from a method in the following way:

public class ProducerConsumerTest {


public static void main(String[] args) {
Contenedor c =newContenedor ();
Producer produces = newProducer (c);
Consumer consume = new Consumer(c);

[Link]();
[Link]();
}
}

Simply create the objects, Container, Productor, Consumer and start them.
threads of these last two.

The synchronization that allows the producer and consumer to operate correctly, that is, the one that
makes the consumer wait until there is data available, and that the producer does not generate
a new one until it has been consumed is in the Container class, it is obtained from the
next form:

public class CubbyHole {


private int data;
private boolean hasData = false;

public synchronized int get() {


while(hayDato == false) {
try{
wait for the producer to set a value
wait();
catch(InterruptedException e) { }
}
hayDato = false;
notify that the value has been consumed
notifyAll();

DistributedSystems::Threads in Java EUI-SG/[Link] 6


return date
}
public synchronized void put(int value) {
while(hayDato == true) {
try{
wait for the data to be consumed
wait();
catch(InterruptedException e) { }
}
data = value;
hayDato =true;
notify that there is already data.
notifyAll();
}
}

The member variable data is the one that contains the value that is stored and returned.
conget. The member variable hasData is an internal flag that indicates whether the object contains data.
oh no.

In the put method, before storing the value in data, it is necessary to ensure that the value
previous has been consumed. If there is still value (thereAreDataTrue) execution is suspended
by the thread using the wait method. Invoking wait (which is a method of the Object class) will
suspend the thread indefinitely until someone sends it a 'signal' with the notify method
notifyAll. When this occurs (in this case, signaling through notify)
produce the method (get) the continuous method, assumes that the data has already been consumed, stores
the value in data and at the same time sends a notifyAll to notify that there is data
available.

On its part, the method checks if there is data available (there isn't if the data is false) and
if there isn't one, wait until you are notified (methodwait). Once you have been notified (from the
methodput) changes the flag and returns the data, but first notifies aputde that the data has already been
has been consumed, and therefore another one can be stored.

The synchronization is carried out using the methods wait and notifyAll.

There is also another basic component in the example: the producer and consumer objects.
they use a shared resource which is the container object. If while the producer calls
methodThis is changing the member variables data and hasData,
the consumer will call the method, and this will start changing these values.
unexpected results may occur (this example is simple but easily imagined
other more complex situations).

It is therefore important that while the method is being executed, no one else accesses the.
member variables of the object. This is achieved with the word synchronized in the
method declaration. When the virtual machine starts the execution of a method with this
modifier acquires a lock on the object on which the method is executed that prevents
no one else initiate the execution on that object from another method that is also declared as
synchronized. In our example, when the put method starts, it locks the object of

DistributedSystems::Threads in Java EUI-SG/[Link] 7


in such a way that if someone tries to invoke the method getoput (both are synchronized)
It will remain on hold until the lock is released (when the execution of the method is finished).
This mechanism ensures that shared objects maintain consistency.

This method of managing the locks implies that:

• It is the programmer's responsibility to think about and manage the locks.


• Synchronized methods are more expensive in the sense that acquiring and releasing
the blockages consume time (this is the reason why they are not synchronized by
default all methods).

DistributedSystems::Threads in Java EUI-SG/[Link] 8

You might also like