java threading

57
Java Threading Chinh Nguyen ([email protected]) Ha Noi 2015

Upload: chinh-ngo-nguyen

Post on 16-Jul-2015

214 views

Category:

Technology


1 download

TRANSCRIPT

Java Threading

Chinh Nguyen ([email protected])

Ha Noi 2015

Topics• Base Thread

• Advance Thread

Part 1 - Base Thread

Contents• Multitasking, Multithreading & Multiprocessing

• Process vs Thread

• Thread Creating methods

• Is Runnable preferred?

• Life cycle of a Thread

• Yield, Sleep vs Wait

• Daemon Thread

• The Thread scheduler

• Thread restart

• Calling run() Method

• Thread Priority

• Synchronization

• Deadlock

• Starvation and Livelock

• Inter-thread communication

• Thread Pool

• Thread Join

Multitasking, Multithreading & Multiprocessing• Multitasking is a process of executing multiple tasks simultaneously. We use

multitasking to utilize the CPU. Multitasking can be achieved by 2 ways:

– Process- based Multitasking (Multiprocessing)

– Thread-based Multitasking (Multithreading)

• Multiprocessing is the use of two or more central processing units (CPUs)

within a single computer system, means execution of multiple concurrent

software processes at any one instant

• Mutithreading is the ability to run several parts of a program in parallel, so

you can subdivide specific operations within a single application into

individual threads. Each of the threads can run in parallel

The OS divides processing time not only among different applications, but

also among each thread within an application

Process vs ThreadThe differences between Process and Threads

• Process: A process runs independently and isolated of other processes. It

cannot directly access shared data in other processes. Cost of

communication is very high.

Switching from one process to another require some time for saving and

loading registers, memory maps, updating list…

• Threads: Threads are so called lightweight processes which have their own

call stack but an access shared data. Threads share same address space.

Cost of communication between the thread is low.

• Process are typically independent, which threads exist as subset of a

process.

Process vs Thread

Thread Creating methods• Extending the Thread class

How to start the threads

Thread Creating methods• Implementing the Runnable interface

How to start the threads

Thread Creating methods• Using the Executor Framework

Is Runnable preferred?

• When creating threads, there are 2 reasons why implementing the Runnable

interface may be preferable to extending the Thread class:

– Java doesn’t support multiple inheritance, Extending the Thread class

means that the subclass cannot extend any other class, whereas a class

implementing the Runnable interface has this option

– Inheriting all Thread methods are additional overhead just for

representing a Task which can be done easily with Runnable

Life cycle of a ThreadThe life cycle of thread is controlled by JVM. The thread states are as follows:

• New: After the creations of Thread instance the thread is in this state but

before the start() method invocation. At this point, the thread is considered

not alive.

• Runnable: A thread start its life from Runnable state. A thread first enters

runnable state after the invoking of start() method but a thread can return to

this state after either running, waiting, sleeping or coming back from blocked

state also.

• Running: A thread is in running state that means the thread is currently

executing. There are serveral ways to enter in Runnable state but there is

only one way to enter in Running state: the scheduler select a thread from

runnable pool.

• Blocked: A thread can enter in this state because of waiting the resources

that are hold by another thread.

• Terminated: A thread can be considered dead when its run() method

completes. If any thread comes on this state that means it cannot ever run

again.

Life cycle of a Thread

Yield, Sleep vs Wait• Yield: This static method is essentially used to notify the system that the

current thread is willing to “give up the CPU” for a while. The thread

scheduler will select a different thread to run instead of the current one.

• Sleep: The Thread.sleep() method effectively “pauses” the current thread for

a given period of time, typically in ms. The sleep can be interrupted.

• Wait: When the thread called wait() means it will blocked untill we call notify(),

notifyAll().

Yield, Sleep vs Wait• Yield: This static method is essentially used to notify the system that the

current thread is willing to “give up the CPU” for a while. The thread

scheduler will select a different thread to run instead of the current one.

• Sleep: The Thread.sleep() method effectively “pauses” the current thread for

a given period of time, typically in ms. The sleep can be interrupted.

• Wait: When the thread called wait() means it will blocked untill we call notify(),

notifyAll().

Daemon Thread• Daemon threads are sometimes called “service” or “background” threads.

These are threads that normally run at a low priority and provide a basic

service to a program when activity on a machine is reduced. An example of a

daemon thread that is continuously running is the garbage collector thread.

To make a thread as a daemon thread in Java.

myThread.setDaemon(true);

The JVM always has a main thread as default. The main thread is always

non-daemon. The user threads are created from the main thread, and by

default they are non-daemon. If you want to make a user created thread to be

daemon (i.e stops when the main thread stops), use setDaemon(true) as

shown above

The Thread Scheduler• The thread scheduler is the part of the JVM that decides which thread should

run

• There is no guarantee that which runnable thread will be chosen to run by the

thread scheduler

• Only one thread at a time can run in a single process

• The thread scheduler mainly uses preemptive or time slicing to schedule the

threads

Preemptive scheduling and Time slicing

Preemptive scheduling, the highest priority task executes unitl it enters the

waiting or dead states or a higher priority task comes into existence

Time slicing, a task executes for a predefined slice of time and then reenters

the pool of ready tasks,

Thread restart• No, after starting a thread, it can never be started again. If you does so, an

IllegalThreadStateException is thrown.

Calling run() Method• Calling run() method directly just executes the code just like a normal method

call. By calling start() method, it starts the execution of the new thread and

calls the run() method. The start() method returns immediately and the new

thread normally continues until the run() method return.

So, don’t make the mistake of calling the run() method directly.

Thread Priority• Each thread have a priority. Priorities are represented by a number between

1 and 10. In most cases, thread scheduler schedules the threads according

to their priority (preemptive), but this is not guaranteed because it depends on

JVM specification that scheduling it chooses

• Three constants defined in Thread class

– MIN_PRIORITY

– NORM_PRIORITY

– MAX_PRIORITY

• Default priority of thread is 5. The min value is 1 and highest priority is 10

Synchronization• Without synchronization, it’s possible for one thread to modify a shared object

while another thread is in the process of using that object’s value. This may

cause improper data and leads to unexpected errors.

• The disadvantage of synchronization is that it can cause deadlocks when 2

threads are waiting on each other to do something. Also synchronized code

has the overhead of acquiring lock, which can slow down the performance.

Deadlock• Deadlock can occur in a situation when a thread is waiting for an object lock,

that is acquired by another thread and second thread is waiting for an object

lock that is acquired by first thread. Since, both threads are waiting for eache

other to release the lock, is called deadlock

Deadlock

• thread A calls oneMethod() while thread B simultaneously calls anotherMethod().

Imagine further that thread A acquires the lock on cacheLock, and at the same

time, thread B acquires the lock on tableLock. Now the threads are deadlocked:

neither thread will give up its lock until it acquires the other lock, but neither will

be able to acquire the other lock until the other thread gives it up.

• When a Java program deadlocks, the deadlocking threads simply wait forever.

While other threads might continue running, you will eventually have to kill the

program, restart it, and hope that it doesn’t deadlock again.

Starvation and Livelock• Starvation and livelock are much less common a problem than deadlock, and

it occurs when all threads are blocked, or are otherwise unable to proceed

due to unavailability of required resources, and the non-existence of any

unblocked thread to make those resources avaiable.

• Livelock: The thread livelock can occur in below ways:

– All of the threads in a program are in infinite loops

– All of the threads in a program execute Object.wait(0) on an object with

zero parameter. The program is live-locked and cannot proceed until one

or more threads call Object.notify() or Object.notifyAll() on the relevant

objects. Because all the threads are blocked, neither call can be made.

• Starvation: Describes a situation where a thread is unable to gain regular

access to shared resources and is unabe to make progress. This happens

when shared resources are made unavailable for long periods by “greedy”

thread.

For example, suppose an object provides a synchronized method that often

takes a long time to return

Inter-thread communication• The wait(), notify() and notifyAll() methods are used to provide an efficient

way for threads to communicate with each other.

• Wait(): causes current thread to release the lock and wait until either another

thread invokes the notify or notifyall() method for this object.

• Notify(): wakes up a single thread that is waiting on this object’s monitor. If

any threads are waiting on this object, one of them is chosen to be

awakened.

• NotifyAll(): wakes up all the threads that are waiting on this object’s monitor.

Thread Pool

Thread Pool• Thread Pools are useful when you need to limit the number of threads

running in your application at the same time. There is a performance

overhead associated with starting a new thread, and each thread is also

allocated some memory for its stack…

• Instead of starting a new thread for every task to execute concurrently, the

task can be passed to a thread pool. As soon as the pool has any idle threads

the task is assigned to one of them and executed. Internally the tasks are

inserted into a Blocking Queue which the threads in the pool are dequeuing

from. When a new task is inserted into the queue one of the idle threads will

dequeue it successfully and execute it. The rest of the idle threads in the pool

will be blocked waiting to dequeue tasks.

• Thread pools are often used in multi threaded servers. Each connection

arriving at the server via the network is wrapped as a task and passesd on to

a thread pool. The threads in the thread pool will process the requests on the

connections concurrently.

Thread Join

• Java Join method, joins the next thread at the end of the current thread.

• After current thread stops execution then next thread executes.

Part 2 - Advance Thread

Contents

• The volatile modifier

• Race conditions

• Semaphores

• Message passing

• Rendezvous

• Remote Method Invocation (RMI)

The volatile modifier• The volatile modifier tells the compiler that the variable is accessed by more

than one thread at a time and inhibits inappropriate code optimizations by the

compiler, such as caching the value of the variable in a CPU register instead

of updating main memory with each assignment to the variable.

• The Java Language Specification guarantees that updates to any one shared

variable by a particular thread are seen by other threads in the order

performed by that particular thread. However, the JLS does not require other

threads to see updates to different shared variables in the order performed by

the updating thread unless the variables are declared volatile.

Race conditions• If two threads execute n=n+1 on a shared variable n at about the same time,

their load and store instructions might interleave so that one thread

overwrites the update of the other.

• This lost update leads to an erroneous result and is an example of a race

condition. Race conditions are possible when two or more threads share

data, they are reading and writing the shared data concurrently, and the final

result of the computation depends on which one does what when.

Race conditions• Example:

Race conditions• Example:

Race conditions• What is output?

– 1st running

– 2nd running

Semaphores• Semaphores can be used for mutual exclusion and thread synchronization.

Instead of busy waiting and wasting CPU cycles, a thread can block on a

semaphore (the operating system removes the thread from the CPU

scheduling or "ready" queue) if it must wait to enter its critical section or if the

resource it wants is not available.

• Java does not have explicit binary and counting semaphores, so they are

provided as classes.

Semaphores• Example:

Semaphores• Example:

Semaphores• Example:

Semaphores• Example:

Semaphores• Example:

Semaphores• What is output?

Message passing• Object-oriented programming blurs the distinction between invoking a method

and sending a message. It also blurs the distinction between shared and

distributed memory computer architectures.

• The figure below shows the difference between (1) invoking a method and (2)

sending a message:

(1) Thread leaves code in one object to execute code in another object,

then comes back (shown at the top of the figure).

(2) Thread sends an object to another thread, then optionally blocks until

the other thread receives the message (shown at the bottom of the

figure).

• Message passing leads to "safer" concurrent programming since the

receiving object only has one thread executing inside it.

Message passing

Message passing• It is important to note that multiple threads invoking methods in an object

might lead to race conditions unless synchronization is properly done by

making the object a monitor. With message passing, the receiving object has

just one thread executing inside it, leading to "safer" concurrent

programming.

• If the threads have a relationship other than client/server, monitors can be

awkward to use. Using message passing between the threads is easier in

these situations. If the threads communicate with each other, they are called

peers or filters. In this situation, the threads form a pipeline in which each

thread gets its input from its predecessor in the pipeline and sends its output

to its successor in the pipeline.

Message passing• Options for user-written classes implementing synchronous (blocking send)

and asynchronous (non-blocking send) message passing (receive always blocks) include:

– Sending object references from one thread to another within the same JVM

– Sending serialized objects through connected sockets from a thread in one JVM to a thread in another JVM

• Each message passing class implements a mailbox or channel shared by a collection of threads.

The one-way flow of information from sender to receiver in synchronous message passing is sometimes called a simple rendezvous.

• Note:

This message passing technique is used for thread communication and synchronization in a computing environment where the threads do not have shared memory (since the threads reside in different virtual or physical machines). Hence the threads cannot share semaphores or monitors and cannot use shared variables to communicate. Message passing can still be used, of course, in a shared memory platform.

Message passing• Example

– Shared type: class Message { … }

Message passing• Example

– Shared mailbox: MessagePassing mailbox = new MessagePassing();

Message passing• Example

– Shared mailbox: MessagePassing mailbox = new MessagePassing();

Message passing• Example

– Sender thread

Message passing• Example

– Receive thread

Message passing• Example

– Client

Rendezvous• In general client-server programming, a client thread interacts with the server

thread by sending a request message followed immediately by a receive that

blocks until the server sends a reply message containing the results of the

request. This is called a rendezvous (or sometimes an extended

rendezvous).

• Here are a few examples:

– Mailbox shared by the client and server:

MessagePassing mailbox = new MessagePassing();

– Client:

send(mailbox, request);

reply = receive(mailbox);

– Server:

request = receive(mailbox);

compute reply;

send(mailbox, reply);

Rendezvous• An extended rendezvous is also called a remote procedure call from a

client to a server (or a worker to the master) because it resembles (and

syntactic sugar can make it nearly identical to) a call to a procedure on a

remote machine that is executed there.

Remote Method Invocation (RMI)• RMI is a Java package (java.rmi) used to make remote procedure calls.

• RMI allows a thread in one JVM to invoke a method in an object in another

JVM that is perhaps on a different computer.

• Object serialization is used to send an object from one JVM to another as

an argument of a remote method invocation. This converts an object into a

byte stream that is sent through a socket and converted into a copy of the

object on the other end. A new thread is created in the remote object to

execute the called method's code.

Thanks!