University of Essex CE303 Advanced Programming Unit 2 PDF
Document Details
Uploaded by ComfortingFeministArt7817
University of Essex
Tags
Summary
This document is lecture notes for a University of Essex course titled 'Advanced Programming'. The notes cover the topic of threads and synchronization in Java, with various examples.
Full Transcript
CE303 Advanced Programming Unit 2 (21st Oct 2024) Threads and Synchronisation Module Supervisor: Dr Tasos Papastylianou ([email protected]) Previously in CE303...
CE303 Advanced Programming Unit 2 (21st Oct 2024) Threads and Synchronisation Module Supervisor: Dr Tasos Papastylianou ([email protected]) Previously in CE303... We reviewed some core concepts of the Java programming language, and Object-Oriented Programming more generally: The relationship between Java and the JVM Inheritance Encapsulation: ‣ Access vs non-access modifiers ‣ Hiding vs Shadowing Abstraction: ‣ Interfaces ‣ Abstract Classes Polymorphism: ‣ Overloading vs Overriding ‣ Upcasting Packages Unit tests (junit5) Functional interfaces, Anonymous Classes, Lambdas, Method References Today’s Learning Objectives: Threads Processes vs Threads Threads in Java Synchronisation The problem of interleaving execution Locks and synchronisation Liveness: Deadlocks, Livelocks, and Starvation Coarse vs fine-grained concurrency More advanced synchronisation ReentrantLock, Semaphore, CyclicBarrier Multithreaded applications vs parallel programming BUT, FIRST! POP QUIZ, HOTSHOTS! 5/N Slide Threads and Synchronisation Part I: Introduction Concurrent Systems A system is concurrent if some of its activities can occur “simultaneously” i.e. “at the same time” in some sense, as opposed to “sequentially”. In a more practical sense, execution of activities can overlap Concurrency in computing: Physical: distributed systems, multi-processor machines, graphics processors, devices (e.g. RAM, I/O, soundcard) Logical: multiple apps/threads running “in parallel” on one device Concurrency may just be virtual e.g. “time-slicing” to run processes concurrently on a single-core machine. Slide 7/N Concurrency: Processes A process is an Operating System (OS) entity, corresponding to an instance of a running program At its simplest, a process is an executing program, with its own process id Modern OSes like Unix or Windows support multiple processes (multitasking). Java MyProg creates a new process. You can open two terminals and run these at the same time. Compare to old DOS systems (ever played a game on DOSBOX?)) Processes are managed by the operating system OS ensures processes do not “interfere” Each process has an independent, isolated address space This means processes do not share variables! Need special mechanisms for communication, like signals, sockets, ‘remote method invocation’, etc Slide 8/N Concurrency: Threads A Thread is an OS entity corresponding to a stream of instructions One or more threads may run (simultaneously) in the context of a process Each thread belongs to exactly one process, and uses its address space Each process has at least one thread (e.g. where the main function is executed) A thread may execute / access any parts of the process code / memory including parts / memory currently being executed / accessed by another thread. Slide 9/N Memory Area Stack Area Class Data Thread 1 Runtime Stack Static variables [Stack Frames / Local Variables] … Method references etc Thread 2 Runtime Stack [Stack Frames / Local Variables] Heap Area … Objects [etc…] … PC Registers [PC for Thread 1] [PC for Thread 2] […] A Java Process Some other process (java?) Slide 10/N Concurrency: Coroutines Processes and threads are not the only kind of concurrency Special mention: coroutines. Compared to threads, where the operating system / execution environment switches between multiple threads in a “pre-emptive” manner (according to a scheduling algorithm), coroutines leave the switching algorithm to the programmer Form of cooperative multitasking by pausing and resuming functions at set points; typically (but not necessarily) on a single thread. E.g. using ‘yield’ statements in python; asyncio.sleep, etc.. More relevant in other languages (particularly where threads are limited) e.g. asyncio in python; the 'cooperative' part is implemented in terms of an 'event loop‘: a python object that keeps track of what is running, what is waiting etc. Slide 11/N OS support for concurrency / parallelism The OS / JVM cooperate to run all the threads “in parallel” (physically or virtually) What if there are more threads than CPU cores? OS uses time-slicing to run several threads concurrently on a single core In general, process scheduling is managed by the OS via a scheduling strategy. In Java, thread scheduling is managed by the JVM, and therefore thread switching does not need to interact with the OS. On most systems, time slicing in threads happens effectively unpredictably and non- deterministically, meaning that a thread may be paused or resumed at any time. Switching processes is expensive (because it involves address space switching). Switching threads is cheaper Allocation of computing resources (i.e. CPU time) is controlled by process and thread priorities Slide 12/N ‘Java’ Threads “Lightweight” concurrent processing Each thread is an independent flow of control, with its own local variables A process can have many threads Threads can share some part of the address space In Java, this means that there may be shared objects that can be accessed from different threads Java threads are managed by the JVM The JVM Thread Scheduler activates / deactivates threads Each Java program starts with one thread: main() Switching threads is relatively fast Slide 13/N Part II: Java Threads Defining and Running a new Thread in Java Define class that implements Runnable Runnable is a functional interface, which only has one method: void run() This method defines what the thread should do when launched. You can think of it as being equivalent to the main() method of the “main” thread. The thread terminates when run() exits Construct an object / instance of this class Construct a Thread instance from this object “Start” the thread. Alternatively: construct a Thread directly via an anonymous class or lambda expression. extend Thread (which also implements Runnable), and override its run() method Pros: Can save a few lines of code; Cons: cannot inherit from other classes due to single inheritance. Slide 15/N public class Greeter implements Runnable { private String greeting; private static final int REPETITIONS = 8; private static final int DELAY = 100; public Greeter(String aGreeting) { greeting = aGreeting; } public void run() { try { for (int i = 1; i