Download presentation
Presentation is loading. Please wait.
1
some important concepts
threads some important concepts Simon Lynch
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 can synchronise with methods, objects (& classes - kinda)
5
synchronising methods
synchronising instance methods... ...or static (class) methods careful because... they synch the object they run on (may not be what you intend) object references can “leak” – adding a reference to some (unsynch’d) structure before something synch’d has completed you cannot synch constructors read...
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: by executing a synchronized instance method of that object. by executing the body of a synchronized statement that synchronizes on the object. 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: these methods should only be called by a thread that owns the object's monitor java says... "interrupts and spurious wakeups are possible" so wrap calls within a suitable condition remember to catch the InterruptedException
10
also… LinkedBlockingQueue < E > 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<SomeType> public SomeType call() { ... blah ... return something of SomeType } ...
13
callables – part 2… ExecutorService executor = ...make some ExecutorService... Future< SomeType > 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<SomeType> future = new FutureTask<SomeType>(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). hypothesise the threading behaviour. how could you test your hypothesis? 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
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.
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… NB: some debate RE: atomic nature of references & primitive types…
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…
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…
21
other notes… reduce concurrent collision problems by favouring immutability generally not a bad idea(?) see... check out the concurrent collections... many/most enforce happens-before relations for multiple concurrent access methods and/before any insertion or update threads
22
a final question… a JFrame application has a responsive UI to drive changes in a continually active set of background tasks what does the Jframe constructor look like? what do the UI handler methods do? how can you decouple thread acitivty to prevent interleaving?
23
a final question… what does the Jframe constructor look like?
public Runner() { initComponents(); Thread runner = new Thread( new RunnableBkground() { public void run() { ...do stuff... } }); runner.start();
24
a final question… what do the UI handler methods do?
how can you decouple thread acitivty to prevent interleaving? use a BlockingQueue to order messages from the UI to the background carefully control message processing with other background threads... synchronize OR wait/notify OR more blocking queues OR middleware
26
threads interleaving threads memory consistency “happens-before”
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 also... reduce concurrent collision problems by favouring immutability to read...
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.