JAVA Threads |
---|
A thread is not an object |
A thread is a flow of control |
A thread is a series of executed statements |
A thread is a nested sequence of method calls |
The Thread Object |
---|
A thread is not an object |
A Thread is an object |
void start() |
Creates a new thread and makes it runnable |
void run() |
The new thread begins its life inside this method |
Runnable Interface |
---|
A helper to the thread object |
The Thread object’s run() method calls the Runnable object’s run() method |
Allows threads to run inside any object, regardless of inheritance |
Runnable Example:
Talker talker = new Talker();
Thread t = new Thread(talker);
t.Start();
---
class Talker implements Runnable {
public void run() {
while (true) {
System.out.println(“yakitty yak”);
}
}
}
Blocking Threads |
---|
When reading from a stream, if input is not available, the thread will block |
Thread is suspended (“blocked”) until I/O is available |
Allows other threads to automatically activate |
When I/O available, thread wakes back up again |
Becomes “runnable” |
Not to be confused with the Runnable interface |
Thread Scheduling |
---|
In general, the runnable thread with the highest priority is active (running) |
Java is priority-preemptive |
If a high-priority thread wakes up, and a low-priority thread is running |
Then the high-priority thread gets to run immediately |
Allows on-demand processing |
Efficient use of CPU |
Thread Starvation |
---|
If a high priority thread never blocks |
Then all other threads will starve |
Must be clever about thread priority |
Thread Priorities: General Strategies |
---|
Threads that have more to do should get lower priority |
Counterintuitive |
Cut to head of line for short tasks |
Give your I/O-bound threads high priority |
Wake up, immediately process data, go back to waiting for I/O |
Thread Synchronization |
---|
Protects access to code, not to data |
Make data members private |
Synchronize accessor methods |
Puts a “force field” around the locked object so no other threads can enter |
Actually, it only blocks access to other synchronizing threads |
Wait and Notify |
---|
Allows two threads to cooperate |
Based on a single shared lock object |
Wait and Notify: Code
Consumer:
synchronized (lock) {
while (!resourceAvailable()) {
lock.wait();
}
consumeResource();
}
Producer:
produceResource();
synchronized (lock) {
lock.notifyAll();
}
Wait/Notify: Details |
---|
Must loop on wait(), in case another thread grabs the resource... |
After you are notified |
Before you acquire the lock and return from wait() |
Use lock.notifyAll() if there may be more than one waiting thread |
Wait/Notify Example: Blocking Queue
class BlockingQueue extends Queue {
public synchronized Object remove() {
while (isEmpty()) {
wait(); // really this.wait()
}
return super.remove();
}
public synchronized void add(Object o) {
super.add(o);
notifyAll(); // this.notifyAll()
}
}