1. Concurrent Programming
What you should know!
- Why do we need concurrent programs?
- What problems do concurrent programs introduce?
- What are safety and liveness?
- What is the difference between deadlock and starvation?
- How are concurrent processes created?
- How do processes communicate?
- Why do we need synchronization mechanisms?
- How do monitors differ from semaphores?
- In what way are monitors equivalent to message-passing?
Can you answer these questions?
- What is the difference between concurrency and parallelism?
- When does it make sense to use busy-waiting?
- Are binary semaphores as good as counting semaphores?
- How could you implement a semaphore using monitors?
- How would you implement monitors using semaphores?
- What problems could nested monitors cause?
- Is it better when message passing is synchronous or asynchronous?

2. Java and Concurrency
What you should know!
- What are finite state processes?
- How are they used to model concurrency?
- What are traces, and what do they model?
- How can the same FSP have multiple traces?
- How do you create a new thread in Java?
- What states can a Java thread be in? 
How can it change state?
- What is the Runnable interface good for?
- What is a critical section?
- When should you declare a method to be synchronized?
Can you answer these questions?
- How would you specify an FSP that repeatedly performs hello, but may stop at any time?
- How many states and how many possible traces does the full TwoThreadsDemo FSP have?
- When should you inherit from Thread?
- How can concurrency invalidate a class invariant?
- What happens if you call wait or notify outside a synchronized method or block?
- When is it better to use synchronized blocks rather than methods?
- How would you model synchronization in FSP?

3. Safety and Synchronization
What you should know!
- How do you model interaction with FSP?
- What is a critical section? What is critical about it?
- Why donÕt sequential programs need synchronization?
- How do locks address safety problems?
- What primitives do you need to implement the busy-wait mutex protocol?
- How can you use FSP to check for safety violations?
- What happens if you call wait or notify outside a synchronized method or block?
- When is it safe to use notifyAll()?
Can you answer these questions?
- What is an example of an invariant that might be violated by interfering, concurrent threads?
- What constitute atomic actions in Java?
- Can you ensure safety in concurrent programs without using locks?
- When should you use synchronize(this) rather than synchronize(someObject)?
- Is the busy-wait mutex protocol fair? Deadlock-free?
- How would you implement a Lock class in Java?
- Why is the Java Slot class so much more complex than the FSP Slot specification?

4. Safety Patterns
What you should know!
- Why are immutable classes inherently safe?
- Why doesnÕt a ÒrelayÓ need to be synchronized?
- What is ÒbalkingÓ? When should a method balk?
- When is partial synchronization better than full synchronization?
- How does containment avoid the need for synchronization?
Can you answer these questions?
- When is it all right to declare only some methods as synchronized?
- When is an inner class better than an explicitly named class?
- What could happen if any of the ExpandableArray methods were not synchronized?
- What liveness problems can full synchronization introduce?
- Why is it a bad idea to have two separate critical sections in a single method?
- Does it matter if a contained object is synchronized or not?

5. Liveness and Deadlock
What you should know!
- What are safety properties? How are they modelled in FSP?
- What kinds of liveness problems can occur in concurrent programs?
- Why is progress a liveness rather than a safety issue?
- What is fair choice? Why do we need it?
- What is a terminal set of states?
- What are necessary and sufficient conditions for deadlock?
- How can you detect deadlock? How can you avoid it?
Can you answer these questions?
- How would you manually check a safety property?
- Why must safety properties be deterministic to be transparent?
- How would you manually check a progress property?
- What is the difference between starvation and deadlock?
- How would you manually detect a waits-for cycle?
- What is fairness?

6. Liveness and Guarded Methods
What you should know!
- When can you apply the Guarded Methods pattern?
- When should methods recheck guard conditions after waking from a wait()?
- Why should you usually prefer notifyAll() to notify()?
- When and where should you issue notification?
- Why must you re-establish the class invariant before calling wait()?
- What should you do when you receive an InterruptedException?
- What is the difference between tracking state and using state-tracking variables?
Can you answer these questions?
- When are guarded methods better than balking?
- When should you use helper methods to implement guarded methods?
- What is the best way to structure guarded methods for a class if you would like it to be easy for others to define correctly functioning subclasses?
- When is the complexity of delegating notifications worthwhile?

7. Lab session I

8. Liveness and Asynchrony
What you should know!
- What general form does an asynchronous invocation take?
- When should you consider using asynchronous invocations?
- In what sense can a direct invocation be ÒasynchronousÓ?
- Why (and how) would you use inner classes to implement asynchrony?
- What is Òearly replyÓ, and when would you use it?
- What are ÒfuturesÓ, and when would you use them?
- How can implement futures and early replies in Java?
Can you answer these questions?
- Why might you want to increase concurrency on a single-processor machine?
- Why are servers commonly structured as thread-per-message gateways?
- Which of the concurrency abstractions we have discussed till now can be implemented using one-slot-buffers as the only synchronized objects?
- When are futures better than early replies? Vice versa?

9. Condition Objects
What you should know!
- What are Òcondition objectsÓ? How can they make your life easier? Harder?
- What is the Ònested monitor problemÓ? 
- How can you avoid nested monitor problems?
- What are ÒpermitsÓ and ÒlatchesÓ? When is it natural to use them?
- How does a semaphore differ from a simple condition object?
- Why (when) can semaphores use notify() instead of notifyAll()?
Can you answer these questions?
- Why doesnÕt SimpleConditionObject need any instance variables?
- What is the easiest way to avoid the nested monitor problem?
- What assumptions do nested monitors violate?
- How can the obvious implementation of semaphores (in Java) violate fairness?
- How would you implement fair semaphores?

10. Fairness and Optimism
What you should know!
- What criteria might you use to prioritize threads?
- What are different possible definitions of fairness?
- What are readers and writers problems?
- What difficulties do readers and writers pose?
- When should you consider using optimistic methods?
- How can an optimistic method fail? How do you detect failure?
Can you answer these questions?
- When does it make sense to split locks? How does it work?
- When should you provide a policy for upgrading readers to writers?
- What are the dangers in letting the (Java) scheduler choose which writer may enter a critical section?
- What are advantages and disadvantages of encapsulating synchronization conditions as helper methods?
- How can optimistic methods livelock?

11. Lab session II

12. Architectural Styles for Concurrency
What you should know!
- What is a Software Architecture?
- What are advantages and disadvantages of Layered Architectures?
- What is a Flow Architecture? What are the options and tradeoffs?
- What are Blackboard Architectures? What are the options and tradeoffs?
- How does result parallelism differ from agenda parallelism?
- How does Linda support coordination of concurrent agents?
Can you answer these questions?
- How would you model message-passing agents in Java?
- How would you classify Client/Server architectures? 
- Are there other useful styles we havenÕt yet discussed?
- How can we prove that the Active Prime Sieve is correct? Are you sure that new Active Primes will join the chain in the correct order?
- Which Blackboard styles are better when we have multiple processors?
- Which are better when we just have threads on a monoprocessor?
- What will happen if you start two concurrent Fibonacci computations?

13. Petri Nets
What you should know!
- How are Petri nets formally specified?
- How can nets model concurrency and synchronization?
- What is the Òreachability setÓ of a net? How can you compute this set?
- What kinds of Petri nets can be modelled by finite state processes?
- How can a (bad) implementation of a Petri net deadlock even though there are enabled transitions?
- If you implement a Petri net model, why is it a good idea to realize transitions as Òthread-per-message gatewaysÓ?
Can you answer these questions?
- What are some simple conditions for guaranteeing that a net is bounded?
- How would you model the Dining Philosophers problem as a Petri net? Is such a net bounded? Is it conservative? Live?
- What could you add to Petri nets to make them Turing-complete?
- What constraints could you put on a Petri net to make it fair?

