![Page 1: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/1.jpg)
Project 2 Overview(Threads in Practice)
CSE451Andrew Whitaker
![Page 2: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/2.jpg)
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
![Page 3: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/3.jpg)
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
![Page 4: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/4.jpg)
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
![Page 5: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/5.jpg)
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
![Page 6: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/6.jpg)
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 () { } }
![Page 7: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/7.jpg)
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
![Page 8: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/8.jpg)
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
![Page 9: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/9.jpg)
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
![Page 10: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/10.jpg)
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!}
![Page 11: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/11.jpg)
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 }}
![Page 12: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/12.jpg)
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()
![Page 13: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/13.jpg)
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.
![Page 14: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/14.jpg)
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
![Page 15: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/15.jpg)
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
![Page 16: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/16.jpg)
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
![Page 17: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/17.jpg)
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
![Page 18: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/18.jpg)
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
![Page 19: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/19.jpg)
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
![Page 20: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/20.jpg)
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
![Page 21: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/21.jpg)
Part 4: GUI Hacking
We provide a simple GUI for calculating the first N fibonacci numbers
You provide an implementation of the cancel button
![Page 22: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/22.jpg)
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
![Page 23: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/23.jpg)
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
![Page 24: Project 2 Overview (Threads in Practice) CSE451 Andrew Whitaker](https://reader036.vdocuments.site/reader036/viewer/2022062401/5a4d1ae57f8b9ab059978eab/html5/thumbnails/24.jpg)
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