Download presentation
Presentation is loading. Please wait.
Published byRoss Homer Hamilton Modified over 9 years ago
1
threads some important concepts Simon Lynch s.c.lynch@tees.ac.uk
2
issues the Thread class & Runnable interface interleaving problems locks synchronization problems with locks wait & notify
3
the thread problem the Thread class & Runnable interface - start & run methods the problem with multiple Threads – “interleaving” - control switches from one thread to another at inconvenient times, eg... // draw blue oval setColor ( blue ) fillOval(... ) //draw green square setColor (green ) fillRect(... )
4
synchronisation synchronisation sets up thread locks... locks (intrinsic lock aka monitor lock aka monitor) - stop chunks of code being interrupted so… …stop threads interleaving acquiring & releasing locks (& write-back) happens automatically with synchronisation NB: some problems with locks (deadlock, starvation, livelock) read... docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html can synchronise with methods, objects (& classes - kinda)
5
synchronising methods synchronising instance methods......or static (class) methods careful because... 1.they synch the object they run on (may not be what you intend) 2.object references can “leak” – adding a reference to some (unsynch’d) structure before something synch’d has completed 3.you cannot synch constructors read... http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
6
synchronising code blocks public class SynchBlob2 extends AbstractBlob implements Runnable { static Object lock = new Object(); public void run() {display(); while( notDeadYet() ) {snooze(); synchronized(lock) {erase(); age(); if( notDeadYet() ) {move(); display(); }
7
monitors Monitors are the objects which synchronization occurs over. Java states that... "a thread becomes the owner of the object's monitor in one of three ways: 1.by executing a synchronized instance method of that object. 2.by executing the body of a synchronized statement that synchronizes on the object. 3.for objects of type Class, by executing a synchronized static method of that class" NB: Only one thread at a time can own an object's monitor.
8
wait & notify public class ProdCom { private Object next; private boolean empty = true; public synchronized Object get() {while (empty) {try {wait(); } catch (InterruptedException e) {} } empty = true; notifyAll(); return next; } public synchronized void put(Object x) {while (!empty) {try {wait(); } catch (InterruptedException e) {} } empty = false; next = x; notifyAll(); }
9
wait & notify check Java API Object docs for... wait() & wait(long) notify() & notifyAll() NB: 1.these methods should only be called by a thread that owns the object's monitor 2.java says... "interrupts and spurious wakeups are possible" so wrap calls within a suitable condition 3.remember to catch the InterruptedException
10
also… LinkedBlockingQueue an AJProgrammers shortcut(?) void put(E e) E take() …and all the stuff from… BlockingQueue Queue Collection …etc
11
thread pools ExecutorService pool = Executors.newFixedThreadPool(poolSize); while ( stillActiveJobsArriving ) { Runnable task = getNextRunnable(); pool.execute(task); } pool.shutdown(); // finish tasks then shut down // Wait until all threads are finish pool.awaitTermination( 5, TimeUnit.SECONDS )
12
callables what if you want values from your threads/runnables? use Callable tasks with executors & futures (easier than it seems!) eg... public class MyTask implements Callable { @Override public SomeType call() {... blah... return something of SomeType }... }
13
callables – part 2… ExecutorService executor =...make some ExecutorService... Future future = executor.submit(new MyTask());...do some stuff maybe, then... try { SomeType result = future.get();...do something with result... } catch (ExecutionException ex) { clean up as required }
14
or use FutureTask… FutureTask future = new FutureTask (new MyTask()); executor.execute(future); try { SomeType result = future.get();...do something with result... } catch (ExecutionException ex) { clean up as required }
15
thread pool workloading this discussion is Java specific… a ThreadPool has 5 worker threads and is given 20 tasks to service; each task runs a loop which performs a Thread.sleep(ms). 1.hypothesise the threading behaviour. 2.how could you test your hypothesis? 3.how difficult would it be to write a new threading API to provide a different behaviour?
16
other issues How to test multi-threaded programs… … to be discussed later in lab sessions Thread.join() allows one thread to wait for the completion of another someOtherThread.join(); …causes the current thread to wait until someOtherThread terminates https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
17
other issues “happens-before” When a statement invokes Thread.start, every statement that has a happens-before relationship with that statement also has a happens- before relationship with every statement executed by the new thread. When a thread terminates and causes a Thread.join in another thread to return, then all the statements executed by the terminated thread have a happens-before relationship with all the statements following the successful join. https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html
18
volatiles #1 class Test { static int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } two threads t1, t2. t1 repeatedly calls Test.one() t1 repeatedly calls Test.two() sometimes t2 will print values such that j > i examples from… http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
19
volatiles #2 class Test { static int i = 0, j = 0; static synchronized void one() { i++; j++; } static synchronized void two() { System.out.println("i=" + i + " j=" + j); } } one way to solve the problem examples from… http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
20
volatiles #3 class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } another way to solve the problem volatile guarantees that access to shared values for i and j occur in the same order during execution of each thread examples from… http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
22
threads interleaving threads memory consistency “happens-before” synchronising methods of a class but object references can “leak” – adding a reference to some (unsynchronised) structure before something synchronised has completed locks (intrinsic lock aka monitor lock aka monitor) acquiring & releasing locks (NB: When a thread releases a lock, happens-before established with any subsequent acquisition of the same lock) deadlock, starvation & livelock implication of “static” synchronised methods wait & notify & notifyAll to read... http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html http://docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.