11-Jun-15 Producer-Consumer An example of using Threads
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.Vector; public class CommandList { static Vector list = new Vector(); public static void put(String s) { // code on next slide } public static String get() { // code on slide after next } }
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: one two three four
The End