Producer-Consumer
Download
Report
Transcript Producer-Consumer
Producer-Consumer
An example of using Threads
1-Apr-16
The problem
One Thread, the producer, is “producing” information (creating
objects), while another Thread, the consumer, is “consuming”
(using) it
We want the consumer to use the objects in the same order as the
producer creates them
We don’t want either Thread to be “loafing”—if there is work for
it to do, the Thread should be doing it
We want to absolutely avoid busy loops
Example busy loop: while (!ready) { }
(the other Thread will reset the ready variable)
Busy loops will consume all available CPU cycles and seriously slow
down everything on the computer
The overall structure
import java.util.ArrayList;
public class CommandList {
static ArrayList list = new ArrayList();
public static void put(String s) {
// code on next slide
}
}
public static String get() {
// code on slide after next
}
Methods in java.lang.Object
void wait()
void wait(long timeout)
Causes the current thread to wait until either another thread invokes the
notify() method or the notifyAll() method for this object, or a specified
amount of time has elapsed.
void notify()
Causes the current thread to wait until another thread invokes the notify()
method or the notifyAll() method for this object.
Wakes up a single thread that is waiting on this object's monitor.
void notifyAll()
Wakes up all threads that are waiting on this object's monitor.
The put method
public static void put(String s) {
synchronized (list) {
list.add(s);
list.notify();
}
}
The synchronized(list) block will take the list object as soon as
it becomes available, and “lock” it so no other
synchronized(list) can use it until this block is completed
There is nothing special about the list object; any object can be
locked for synchronization
The get method
}
public static String get() {
if (list.size() > 0) {
synchronized (list) {
return (String)list.remove(0);
}
} else {
try {
synchronized (list) {
list.wait();
return get();
}
} catch (InterruptedException e) {
return "InterruptedException";
}
}
}
The Consumer class
public class Consumer extends Thread {
public void run() {
while (true) {
String s = CommandList.get();
System.out.println("Consuming " + s);
}
}
}
The test class
public class CommandListTester {
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.start();
CommandList.put("one");
CommandList.put("two");
sleep(2000);
CommandList.put("three");
CommandList.put("four");
}
}
private static void sleep(int ms) {
try { Thread.sleep(ms); }
catch (InterruptedException e) {
}
}
Output:
Consuming one
Consuming two
Consuming three
Consuming four
Another Consumer class
import java.util.Random;
public class Consumer2 extends Thread {
static Random rand = new Random();
}
public void run() {
while (true) {
String s = CommandList.get();
System.out.println("Consuming " + s);
try {Thread.sleep(rand.nextInt(1000)); }
catch (InterruptedException e) { }
}
}
Another test class
import java.util.Random;
public class CommandListTester2 {
static Random rand = new Random(100);
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.start();
String[] words = { "one", "two", "three", "four", "five", "six" };
}
}
for (int i = 0; i < words.length; i++) {
CommandList.put(words[i]);
try {
Thread.sleep(rand.nextInt(1000));
}
catch (InterruptedException e) { }
}
The End