Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Threads and Synchronization in Java
Introduction To Threads
Basic concepts have been around for almost as long as operating
systems.
Threads are getting more attention and are available in modern
programming languages.
Allow multiple tasks to be executed
Allow a single program multiple threads/lines/paths of control.
Traditionally operating systems can “fork” a process to run in parallel
with the main process
Processes have much higher overhead.
Primitive mechanisms to coordinate.
Threads have much lower overhead.
Conceptually threads are cleaner to use
1
Threads and Synchronization in Java
Performance Improvement for single applications
How to improve the performance of individual programs.
•
•
•
•
•
•
•
If the process is I/O bound, then multiple threads don't help.
If the process is CPU bound and can support multiple lines of execution,
then each line can be a thread.
Each thread can be executed on a different processor.
Shared memory model (compared with processes) used by threads
minimizes the memory management problems.
Overall runtime can be improved.
The popularity of threads is directly correlated with the rise of
multiprocessors and increased demand for better performance of large
scientific applications.
Graphical user applications and games programs rely on threading.
2
Threads and Synchronization in Java
PC
PC
PC
PC
PC
Single Threaded Process
MultiThreaded Process
Traditionally a process abstracts the execution of a program.
In a threaded environment, threads provide another level of abstraction
(below processes)
Thread: Single line or stream of control, where each stream can execute
its own instructions.
A thread looks much like a process – it can be regarded as a lightweight
process
3
Threads and Synchronization in Java
A Process is more than a Thread
Process is a kernel level entity, i.e. created by kernel in the kernel mode.
The threads may be created at user level.
Process structures must keep information about the page tables, file
descriptors, user ID, etc. Much of the information is not thread specific. It
is global and may be shared by multiple threads.
The process table is kept in kernel space, user can not touch this data
structure.
The thread structure is kept in user space. Created and managed using
library calls that may be thought of as user-level functions.
All threads in a process share the same process state. I.e. same memory
map, file descriptors, same data and text segments. They have their own
stack. One threads opens/reads a file, others see the file pointer change.
The kernel may not even know there are threads in the system.
A Kernel is a small set of data structures and subroutines that are at the core of any
concurrent program
4
Threads and Synchronization in Java
Advantages of Threads
Threads are cheap : Implemented at user levels, no kernel resources.
Threads are fast : No system calls, switching modes involved.
Interactive Responsiveness
•
Separate Computation and I/O threads
•
I/O threads (in interactive situations) return quickly giving better
response times.
•
Multiple connections for multiple threads.
•
Better performance
•
Simpler programing (conceptually)
•
Easier to scale
5
Threads and Synchronization in Java
Threads and Program Structure
Some applications have complex structure.
Sometimes they can be more cleanly modeled using multi threaded
paradigm.
Easy to write, understand and debug.
Threads and Processes
Process (Uses fork() to start a new process)
•
Child process gets a copy of parents variables
•
Relatively expensive to start
•
Don't have to worry about concurrent access to variables
Thread (uses standard language construct)
•
Child process shares parents variables
•
Relatively cheap to start
•
Concurrent access to variables is an issue.
6
Threads and Synchronization in Java
Threads In Java
Thread is a separate activity which shares the same name space as the
program that created the thread.
Thread can be in one of four states
•
New - occurs when a thread is created, but not yet running
•
Runnable - occurs when you invoke start on a thread (when executing
it is running)
•
Blocked - occurs when:
o someone calls sleep() method on the thread
o someone calls suspend() method on the thread
o the thread calls the wait() method
o the thread calls an operation that is blocking on input/output
•
Dead - a thread becomes dead if
o it dies an natural death because the run method exits
o someone invokes its stop method (can be dangerous!)
7
Threads and Synchronization in Java
Thread States
Note. A thread can be given a priority, which facilitates preemptive
scheduling (i.e. a lower priority thread being stopped to allow a
higher priority thread to run.
8
Threads and Synchronization in Java
Thread Class Methods
void start()
Creates a new thread and makes it runnable. This method can be called only once
void run()
The new thread begins its life inside this method
void stop() (deprecated)
The thread is being terminated
void yield()
Causes the currently executing thread object to temporarily pause and allow other
threads to execute. Allow only threads of the same priority to run
void sleep(int m) or sleep(int m, int n)
The thread sleeps for m milliseconds, plus n nanoseconds
t.join()
If t is a Thread object whose thread is currently executing. T.join() causes the current
thread to pause execution until t's thread terminates.
9
Threads and Synchronization in Java
Creating Threads
There are two different methods for creating a thread
First Method to create a thread
Create a new subclass of the Thread class and override the run method,
for example:
getName() returns the
class SimpleThread1 extends Thread
name of the thread – in
{
this case a default name
public void run()
{
for ( int count = 0; count < 4; count++)
System.out.println( "Message " + count + "From: " + getName() );
}
}
Note. SimpleThread1 is now a subclass of the Thread class
10
Threads and Synchronization in Java
Creating Threads
A SimpleThread object(i.e. parallel) can now be created and started
running (using parallel.start()) to run in parallel with the main method
thread itself.
We now have two threads of execution.
class TestThread
{
public static void main( String[] args )
{
Creating the parallel
SimpleThread1 parallel = new SimpleThread1();
thread object
System.out.println( "Create the thread");
Starting the parellel thread
parallel.start();
System.out.println( "Started the thread" );
System.out.println( "End" );
}
}
11
Threads and Synchronization in Java
The resulting output from the above program is as follows:
Create the thread
Main Thread (Program) output
Started the thread
End
Message 0 From: Thread-2
Message 1 From: Thread-2
Message 2 From: Thread-2
Parallel Thread (object) output
Message 3 From: Thread-2
Message 4 From: Thread-2
This output could appear here if
the parallel thread started
running immediately
12
Threads and Synchronization in Java
Creating Threads
Second method to create a Thread
The second way of creating threads is to implement the Runnable interface
(provided by Java) in a class and then an object of this class is passed to the
Thread constructor which makes it into a thread that can then be started.
For example:
class SimpleThread2 implements Runnable
{
SimpleThread2 is a class that must implement the
public void run()
run() method since it implements Runnable
{
for ( int count = 0; count < 4; count++)
System.out.println( "Message " + count + " From: " +
Thread.currentThread().getName() );
}
}
13
Threads and Synchronization in Java
Now consider a main program that instantiates a Runnable object
(i.e. notAThread) and passes it as a parameter to the constructer of
Thread.
The thread object (i.e. parallel) can now be started.
class TestThread
{
public static void main( String[] args )
{
Creating object that
SimpleThread2 notAThread = new SimpleThread2();
can become a thread
Thread parallel = new Thread( notAThread );
System.out.println( "Create the thread");
Making “notAThread” into
a thread referenced as
parallel.start();
“parallel”
System.out.println( "Started the thread" );
System.out.println( "End" );
}
14
}
Threads and Synchronization in Java
The resulting output from the above program is as follows:
Create the thread
Main Program output
Started the thread
End
Message 0 From: Thread-4
Message 1 From: Thread-4
parallel Thread output
Message 2 From: Thread-4
Message 3 From: Thread-4
This output could appear here if
parallel thread starts immediately
15
Threads and Synchronization in Java
Giving a Thread a Name
Giving a thread a name when creating it allows us to identify that thread.
For example, first define a class (i.e. MyMum) that implements Runnable.
class MyMum implements Runnable
{
public void run()
{
for ( int count = 0; count < 4; count++)
System.out.println( "Message " + count + " From: " +
Thread.currentThread().getName() );
}
Note. This uses the second method for
}
creating a thread – MyMum is a class that
has the potential to be used to create
thread objects
16
Threads and Synchronization in Java
Giving a Thread a Name
Now, pass this runnable class as the first parameter to the Thread
constructer and the thread identifier (as a string) as the second parameter.
class TestThread
{
public static void main( String[] args )
{
MyMum notAThread = new MyMum();
Thread parallel = new Thread( notAThread, "Mom" );
The thread referenced
System.out.println( "Create the thread");
by “parallel” has a
parallel.start();
textual name associated
System.out.println( "Started the thread" ); with it called “Mom”
System.out.println( "End" );
}
}
17
Threads and Synchronization in Java
The resulting output from this program is as follows:
Create the thread
Main Program output
Started the thread
End
Message 0 From: Mom
Message 1 From: Mom
Output from the thread
referenced by “parallel”
Message 2 From: Mom
Message 3 From: Mom
18
Threads and Synchronization in Java
Creating a Thread with Multiple Constructors
class SimpleThread extends Thread
{
private int maxCount = 32;
Default number of repetitions
public SimpleThread( String name )
{
super( name );
}
First Constructor just
accepts a textual “name”
that will be given to any
thread created using it
public SimpleThread( String name, int repetitions )
Second Constructor accepts a
{
textual “name” and the
super( name );
number of repetitions that
maxCount = repetitions;
will be given to any thread
created using it
}
19
Threads and Synchronization in Java
Creating a Thread with Multiple Constructors
public SimpleThread( int repetitions )
Third Constructor just
{
accepts number of
repetitions
maxCount = repetitions;
}
public void run()
{
for ( int count = 0; count < maxCount; count++)
{
System.out.println( count + " From: " + getName() );
}
}
}// end SimpleThread
(This SimpleThread will be used in later examples)
20
Threads and Synchronization in Java
Showing some parallelism - two threads + main program
In this example we use the SimpleThread class (above) to create two
threads called “A” and “B” to run in parallel with the main program.
class TestThread
{
public static void main( String[] args )
{
SimpleThread first
= new SimpleThread( “A”, 5 );
SimpleThread second = new SimpleThread( “B”, 5 );
first.start();
Three threads started at this
point “first”, “second” and
second.start();
the “main” program thread
System.out.println( "End" );
}
}
21
Threads and Synchronization in Java
The resulting output is then as follows:
End
The main thread finished execution
0 From: Thread-A
1 From: Thread-A
Next the “first” thread was
scheduled to run and ran to
2 From: Thread-A
completion
3 From: Thread-A
4 From: Thread-A
0 From: Thread-B
1 From: Thread-B
Now the “second” thread
2 From: Thread-B
was scheduled to run
3 From: Thread-B
4 From: Thread-B
Note that thread A produced all its output before thread B got a chance
to output anything. Also the main program thread completed its output
even before thread A.
22
Threads and Synchronization in Java
Setting Thread Priority
public final static int MIN_PRIORITY = 1
public final static int NORM_PRIORITY = 5
public final static int MAX_PRIORITY = 10
class TestThread
{
public static void main( String[] args )
{
SimpleThread first = new SimpleThread(“A”, 5 );
SimpleThread second = new SimpleThread(“B”, 5 );
second.setPriority( 8 );
first.start();
second.start();
System.out.println( "End" );
}
}
23
Threads and Synchronization in Java
As shown above we can schedule the threads to run(execute) in a
different order (Preemptive Priority) by giving them different
priorities.
The higher priority thread gets preference; so the resulting output is:
0 From: Thread-B
1 From: Thread-B
“second” thread got in to
2 From: Thread-B
run first
3 From: Thread-B
4 From: Thread-B
0 From: Thread-A
1 From: Thread-A
“first” thread got in to run
2 From: Thread-A
next
3 From: Thread-A
4 From: Thread-A
“main” thread only completes now
End
24
Threads and Synchronization in Java
Thread Scheduling
Thread scheduling is the mechanism used to determine how runnable threads
are allocated CPU time.
A thread-scheduling mechanism is either preemptive or non-preemptive.
Preemptive scheduling
the thread scheduler preempts (pauses) a running thread to allow different
threads to execute
Non-preemptive scheduling – the scheduler never interrupts a running thread.
The non-preemptive scheduler relies on the running thread to yield control of
the CPU so that other threads may execute.
A nonpreemptive scheduler may cause starvation (runnable threads, ready to be
executed, wait to be executed in the CPU a very long time, maybe even
forever)
Sometimes, starvation is also called a livelock.
25
Threads and Synchronization in Java
Time-sliced Scheduling
Non-time-sliced Scheduling
The scheduler allocates a period of time that each thread can use the CPU.
When that amount of time has elapsed, the scheduler preempts the thread and
switches to a different thread
Non-time-sliced scheduler
the scheduler does not use elapsed time to determine when to preempt a thread
it uses other criteria such as priority or I/O status.
Java Scheduling
Scheduler is pre-emptive and based on priority of threads.
Uses fixed-priority scheduling:
Threads are scheduled according to their priority with respect to other threads in the
ready queue.
The highest priority runnable thread is always selected for execution above lower
priority threads
Java threads are guaranteed to be preemptive-but not time sliced
When multiple threads have equally high priorities, only one of those threads is
guaranteed to be executing
26
Threads and Synchronization in Java
Daemon Threads
Race Condition
Daemon threads are “background” threads, that provide services to other
threads, e.g., the garbage collection thread
The Java VM will not exit if non-Daemon threads are executing
The Java VM will exit if only Daemon threads are executing
Daemon threads die when the Java VM exit.
A race condition – the outcome of a program is affected by the order in
which the program's threads are allocated CPU time
Two threads are simultaneously modifying a single object
Both threads “race” to store their value
Critical Section
A critical section is a piece of code that accesses a shared resource (data
structure or device) that must not be concurrently accessed by more than
thread of execution.
27
Threads and Synchronization in Java
Simple Yield Example
class YieldThread extends Thread
{
public void run()
{
for ( int count = 0; count < 4; count++)
{
System.out.println( count + "From: " + getName() );
yield();
This thread halts execution after each line it
}
prints and lets another waiting thread have
control of the CPU
}
}
The thread gives up it right to execute by calling the yield method
28
Threads and Synchronization in Java
We can now test YieldThread as follows:
class TestThread
{
public static void main( String[] args )
{
YieldThread first = new YieldThread();
YieldThread second = new YieldThread();
first.start();
second.start();
System.out.println( "End" );
}
}
29
Threads and Synchronization in Java
The output will then be as follows:
End
0 From: Thread-4
0 From: Thread-5
1 From: Thread-4
1 From: Thread-5
2 From: Thread-4
2 From: Thread-5
3 From: Thread-4
3 From: Thread-5
Output from thread “first”
Output from thread “second”
Note the interleaving of
output between the two
threads
30
Threads and Synchronization in Java
Sleep Example- two threads in parallel (one sleepy, one alert)
class SleepyThread extends Thread
{
public SleepyThread( String name )
{
super( name );
}
public void run()
{
for ( int count = 0; count < 4; count++)
{
System.out.println( count + " From: " + getName() );
try
{
This thread sleeps for
sleep( 5 ); // in milliseconds
a while after each print
}
statement
catch ( InterruptedException ignored ) {}
}
}
}
31
Threads and Synchronization in Java
Sleep Example- two threads in parallel (one sleepy, one alert)
Now give the sleepy one a high priority
class TestSleep
{
public static void main( String[] args )
{
SimpleThread alert = new SimpleThread( "Alert", 32 );
SleepyThread sleepy = new SleepyThread( "Sleepy" );
sleepy.setPriority( 8);
alert.start();
sleepy.start();
System.out.println( "End" );
}
}
32
Threads and Synchronization in Java
“Sleepy”get in
first
because it has a
higher priority,
but it then goes
to sleep which
lets in “alert”
“Sleepy”gets
back in some time
later
“main”gets a chance
to complete
The resulting output is as follows (read down left column first):
0 From: Sleepy
0 From: Alert
1 From: Alert
2 From: Alert
3 From: Alert
4 From: Alert
5 From: Alert
6 From: Alert
7 From: Alert
8 From: Alert
9 From: Alert
10 From: Alert
11 From: Alert
12 From: Alert
13 From: Alert
14 From: Alert
1 From: Sleepy
End
15 From: Alert
16 From: Alert
….
17 From: Alert
18 From: Alert
19 From: Alert
20 From: Alert
21 From: Alert
22 From: Alert
23 From: Alert
24 From: Alert
25 From: Alert
26 From: Alert
27 From: Alert
28 From: Alert
2 From: Sleepy
29 From: Alert
30 From: Alert
31 From: Alert
3 From: Sleepy
“Sleepy”again
“Sleepy”finally
finishes
...
33
Threads and Synchronization in Java
Join - Waiting for Thread to end
The thread that invokes join, waits until the target thread has completed
class Godot
{
public static void main( String[] args ) throws
InterruptedException
{
SimpleThread lowly = new SimpleThread( "Lowly" , 32);
lowly.setPriority( 1 );
lowly.start();
System.out.println( "now I can go" );
Program waits here until “lowly”
lowly.join();
thread has finished execution
System.out.println( "Done" );
}
34
Threads and Synchronization in Java
Main program
output
The results are as follows:
now I can go
0 From: Lowly
1 From: Lowly
2 From: Lowly
3 From: Lowly
4 From: Lowly
5 From: Lowly
6 From: Lowly
7 From: Lowly
8 From: Lowly
9 From: Lowly
10 From: Lowly
11 From: Lowly
12 From: Lowly
13 From: Lowly
14 From: Lowly
15 From: Lowly
16 From: Lowly
17 From: Lowly
18 From: Lowly
19 From: Lowly
20 From: Lowly
21 From: Lowly
22 From: Lowly
23 From: Lowly
24 From: Lowly
25 From: Lowly
26 From: Lowly
27 From: Lowly
28 From: Lowly
29 From: Lowly
30 From: Lowly
31 From: Lowly
Remaining
Done
Main program
output
Note The main program waits for the “lowly” thread to
complete before executing its final print statement
35
Threads and Synchronization in Java
Synchronization
When threads share information you need to synchronize the threads to get
the desired result
•
(i.e. the concurrent processing of the different threads must be
coordinated in their contribution to the overall task.)
For example, when two threads need to use the same file there is the
possibility that interleaved operations can corrupt the data.
So the question we need to ask is what happens when two threads access
the same method/data?
To be able to give a reliable answer we need to address mutual exclusion.
36
Threads and Synchronization in Java
Example
Suppose two threads simultaneously carry out the instruction:
accounts[to] += amount;
The problem is that this is not an atomic transaction. It might be processed
as follows:
1) LOAD accounts[to] into a register
2) ADD amount
3) MOVE the result back to accounts[to]
Now if:
(a) ThreadA executes steps 1 and 2 and is then interrupted;
(b) ThreadB awakens and updates the same entry in the accounts array
(c) ThreadA awakens and completes it’s step 3.
•
The effect can be illustrated as follows:
37
Threads and Synchronization in Java
Thread A
LOAD
5000
ADD
5500
Thread B
accounts[to]
6000
5500
LOAD
5000
ADD
6000
STORE
6000
Problem: ThreadB’s has been
wiped out.
Solution: Make this code
an atomic transaction so
that it cannot be interrupted
before it completes.
5500
38
Threads and Synchronization in Java
Synchronized Methods
To make a class useable in a multithreaded environment, the appropriate
methods are declared synchronized.
If one thread invokes a synchronized method on an object, the object is
locked. Another thread invoking a synchronized method on the same object
will block until the lock is released.
So synchronization forces execution of the two threads to be mutually
exclusive in time.
Wait to acquire lock
39
Threads and Synchronization in Java
Example - An Account class that facilitates the reading/writing of a
balance value could be developed to work in a multi-threaded
environment as follows:
class Account
{
private double balance;
public Account (double initialDeposit)
{
balance = initialDeposit;
}
public synchronized double getBalance()
Atomic
{
return balance;
}
public synchronized void deposit(double amount)
{
Atomic
balance += amount;
}
getBalance and deposit are now mutually exclusive
}
40
Threads and Synchronization in Java
Using wait() and notify()
In addition to avoiding thread interference, we may require them to
communicate with each other in a particular way to carry out some overall
task; wait() and notify() facilitate this.
the wait method is defined to enable waiting until some condition
occurs
the notify is defined to tell those waiting that something has occurred
The wait() and notify() methods apply to particular objects; so when you
wait for an event, you are waiting for some other thread to notify you of
that event on the same object that you are waiting on.
The two communicating threads usually do something like this:
The waiting thread:
synchronized void doWhenCondition() {
while (!condition)
wait();
… Do what needs doing when the condition is true …
}
41
Threads and Synchronization in Java
The notifying thread
synchronized void changeCondition() {
… change some value used in a test condition …
notify();
}
Multiple threads may be waiting on the same object.
Using notify() wakes up the one that has been waiting the longest.
notifyAll() wakes up all of them.
Producer/Consumer Problem
A classical problem
PRODUCER
Thread
(Producer places a
single value into
single buffer)
7
Single
Buffer
CONSUMER
Thread
(Consumer takes a
single value out of
the single buffer)
42
Threads and Synchronization in Java
Synchronization is necessary because:
If the consumer has not taken out the current value in the buffer then the
producer should not replace it with another.
Similarly the consumer should not consume the same value twice.
Solution is to provide correct communication between
producer/consumer threads
Make the buffer and the code that places/removes values from it a critical
region by placing it in a monitor (i.e. declare the buffer access methods as
synchronized and use the wait() and notify() to halt or activate the current
thread respectively.
Use a boolean variable full to indicate if the buffer is currently full or
empty.
put()
get()
43
Threads and Synchronization in Java
The monitor to provide the required communication is:
class singleBufferMonitor {
private int buffer;
private boolean full;
public singleBufferMonitor() {
full = FALSE;
// set the full flag to FALSE initially
}
public synchronized int get() {
while (full ==FALSE) { // if necessary wait for buffer to become full
wait();
}
return buffer; // return contents of buffer
notify(); // notify any waiting producers that buffer is now empty
full = FALSE;
}
44
Threads and Synchronization in Java
public synchronized void put(int value) {
while (full=TRUE) { // if necessary wait for the buffer to become empty
wait();
};
buffer = value; // place value in buffer
full = TRUE;
notify(); // notify the waiting consumer that the buffer is now full
}
}
Now when the producer (thread) wishes to place a value in the buffer it
calls put();
Similarly when the consumer (thread) wishes to take a value out of the
buffer it calls get().
Using only put() and get() means that the buffer activity is synchronized
- no value gets overwritten;
- the consumer does not read the same value twice;
45
Threads and Synchronization in Java
Using the synchronized buffer
class TestSyncBuffer;
{
public static void main( String[] args ) throws Exception
{
singleBufferMonitor box = new singleBufferMonitor(); // create a buffer monitor
ProducerThread producePerson = new ProducerThread( ); // create a producer
ConsumerThread consumePerson = new ConsumerThread(); //create a consumer
producePerson.start();
consumePerson.start();
}
}
A synchronized buffer called box and a producer producePerson and
consumer consumePerson thread (defined below) are created to
communicate via the buffer.
The producer puts the numbers 0..9 in the box and the consumer reads them
from the box and prints them.
46
Threads and Synchronization in Java
class ConsumerThread extends Thread {
private int aValue;
public void run() {
for ( int count = 0; count < 10; count++)
{
aValue = box.get();
System.out.println( aValue + "From: " + getName() );
}
}
} // end ConsumerThread
class ProducerThread extends Thread {
public void run() {
for ( int count = 0; count < 10; count++)
{
box.put(count);
}
}
} // end ProducerThread
47
Threads and Synchronization in Java
Multiple Buffer
Sometimes a single buffer is not very efficient (e.g. variable rate producer)
and a larger buffer is used.
put()
Producer
Cyclic Queue
get()
Consumer
The producer can keep adding values if the buffer is not full.
The consumer can keep taking out values if the buffer is not empty.
A larger buffer tends to smooth out the communication flow between
the producer and the consumer.
48
Threads and Synchronization in Java
Deadlocks
Whenever you have two threads and two objects with locks, you can have a
deadlock, where each object is waiting for the lock on the other.
If object X has a synchronized method that invokes a synchronized method
on object Y, which in turn has a synchronized method invoking a
synchronized method on object X, both objects will wait for the other to
complete in order to get a lock, so neither will run.
This situation is called a ‘deadly embrace’.
Example of deadlock
object - AccountX: £2000; object - AccountY:£3000
threadA - transfers £3000 from AccountX to AccountY(blocked!)
threadB - transfers £4000 from AccountY to AccountX(blocked!)
Nothing Java can do to avoid deadlock;
design your program to avoid deadlock.
Analyze your program and ensure that every thread awaiting a signal will
eventually be activated.
49
Threads and Synchronization in Java
Deadlock (deadly embrace)
Thread B
Thread A
objectX (lockA)
synchronized methodA takes lockA
{
...
Waiting to
objectY.methodB();
gets lockB
...
}
objectY (lockB)
synchronized methodB
{
...
objectX.methodA();
...
}
takes lockB
Waiting to
gets lockA
Deadlock
(deadly embrace)
occurs
50
Threads and Synchronization in Java
Summary
Each thread in Java acts like a single sequential program. The scheduler
shares the time out among the threads that are ready to execute.
Strange, non-deterministic things can happen if two or more threads have
uncontrolled access to some shared variables.
There is therefore the need for mutual exclusion.
Synchronised methods are used to provide mutual exclusion, where
only one thread at a time has access to an object that has synchronised
methods.
Threads often collaborate in some goal, passing information from one to
another.
Each pair of threads is called a ‘producer-consumer’ pair, with an
intermediary object(i.e. buffer) providing synchronised methods for
entering information into the object and removing items from the
object.
If care is not exercised during design, deadlock can occur in parallel
programs!
51