Upload
charla-vivian-marshall
View
222
Download
0
Embed Size (px)
DESCRIPTION
General Instructions Your programs must use proper synchronization Working functionality is not enough! Remember the rules we’ve talked about: All shared, mutable state must be properly synchronized Usually with a synchronized block or method Compound actions must be protected by a single lock Start early! Not a huge amount of code, but a lot of new concepts Thursday’s discussion will be Q & A
Citation preview
Project 2 Overview(Threads in Practice)
CSE451Andrew Whitaker
Project 2 Overview
Project consists of threaded Java programs No VMWare / kernel hacking
You can use any multi-processor Linux machine Most (all?) undergrad lab machines are dual core Also, you have access to amlia.cs.washington.edu
Run ‘more /proc/cpuinfo’ to verify Continue to work in your project teams
General Instructions
Your programs must use proper synchronization Working functionality is not enough!
Remember the rules we’ve talked about: All shared, mutable state must be properly synchronized
Usually with a synchronized block or method Compound actions must be protected by a single lock
Start early! Not a huge amount of code, but a lot of new concepts
Thursday’s discussion will be Q & A
Using Other People’s Code
Do it! e.g., java.util.LinkedList, java.util.ArrayList, …
But, understand the implications for threading May require documentation diving
Part 1: Implementing Semaphores
Semaphore is a thread-safe integer Supports up and down operations for increment
/ decrement The semaphore can never go negative
If value == 0, then down blocks before decrementing Thread is added to a wait queue
If value == 0, then up wakes up a thread after incrementing
Semaphore with value 1 is a lock
Pseudocode
public class Semaphore { private int count;
// block if count == 0 // else, decrement public void down () { }
// increment count // wake up somebody (if necessary) public void up () { } }
Semaphores, Continued
Condition variables and semaphores have equivalent expressive power One can be implemented with the other
Your task: demonstrate this with Java code Your solution should not busy wait
Do not use java.util.concurrent.Semaphore Or any other off-the-shelf semaphore implementation
Part 2: Calculating
Step 1: approximate using a random number generator
Step 2: Convert this program to a multi-threaded program
Step 3: Benchmark the program with a variable number of threads
Approximation Hint
Consider a circle inscribed in a square
Imagine throwing a large number of darts at the square
Some fraction of darts will also hit the circle Use this fraction to calculate
Multi-threaded Calculator
Approximating requires many samples 10s of millions is a reasonable starting point
So, let’s try decomposing the work across multiple threads
public double calculate(int numSamples, int numThreads) { return 0.0; // TODO: implement this!}
Mapping This to Code
Java’s Thread join method is useful for these sorts of computations
public double calculate(int numSamples, int numThreads) { Thread [] threads = new Thread[numThreads]; for (int i=0;i <= numThreads; i++) { threads[i] = new WorkerThread(…); threads[i].start(); }
for (int i=0;i <= numThreads; i++) { try { threads[i].join(); // wait for thread termination } catch (InterruptedException ie) {} //ignored }}
Benchmarking
Create a graph with # threads on the x-axis and latency on the y-axis
Let threads range from 1 to 10Number of samples should be fixed
Each thread does a fraction of the total samplesMeasure latency with System.currentTimeMillis()
Part 3: Multi-threaded Web Server
Task: convert a single-threaded web server to a multi-threaded web server
Why? Any high-throughput web server must handle multiple
requests in parallel By default, each thread handles one request at a time Requests are blocking
Thread is stalled while waiting for network, disk, etc.
Anatomy of a (Single-threaded) Web Server
1. Accept a new Socket2. Read from socket to extract
request URI (e.g., index.html)3. Read desired file into a buffer4. Write file over the socket5. Close the socket
while (true) {
}
These areblocking calls
Possible Alternate Approach: Thread-per-request
1. Accept a new Socket2. Fork a thread
while (true) {
}1. Read from socket 2. Read desired file into a buffer3. Write file over the socket4. Close the socket5. Thread exits
Analysis of Thread-per-Request
Advantage: supports simultaneous requests (and higher throughput) Blocking operations only stall one thread
Disadvantages: Thread creation is expensive
Must create PCB, allocate stack Thread teardown is expensive Too many threads can lead to poor
performance
Preferred Solution: Thread Pool
On startup, create a static pool of worker threads
Each thread loops forever, processing requests
Advantages: Thread allocation cost is paid
only once Threads are never deallocated
Thread Pool, Implementation Overview
1. Accept a new Socket2. Enqueue Socket
while (true) {
}1. Dequeue Socket2. Read from socket 3. Read desired file into a buffer4. Write file over the socket5. Close the socket
while (true) {
}
Accept thread
Worker threads
Web Server, Continued
Step 2: Add a “statistics” page at http://hostname/STATS Req/sec over the previous ten seconds Number of currently active threads Number of idle threads
Step 3: Benchmark the web server Using the provided benchmark tool
Java Timers
See lecture or condition variables OR, java.util.Timer and
java.util.TimerTaskKey point: timers run in a separate thread
So, shared state must be properly synchronized
Part 4: GUI Hacking
We provide a simple GUI for calculating the first N fibonacci numbers
You provide an implementation of the cancel button
Challenge
Problem: GUI frameworks are single-threaded Long-lived computations can make the GUI
unresponsiveSolution: Transfer long-lived tasks to a
separate thread Requires coordination between the GUI thread
and the helper thread
Things You Need to Understand
How task handoff works in the Swing GUI framework? In particular, SwingUtilities.invokeLater
How does thread interruption work? Via Thread.interrupt
Thread Interruption
You can call interrupt on any ThreadWhat happens?
If the thread was blocked, it receives an InterruptedException
If the thread is ready or running, it has an interrupted flag set
The thread must explicitly check this flag with Thread.isInterrupted