Biblioteca Java - Blame information for rev 28

Subversion Repositories:
Rev:
Rev Author Line No. Line
28 mihai 1 package exemple.exchanger;
2  
3 import java.util.*;
4 import java.util.concurrent.*;  
5  
6 /*
7  * Exchanger offers a simplified way of communicating between threads, that is, by passing
8  * a specific object between two threads. That's why there's the <V> after the class
9  * name. Instead of using Piped streams for stream-based, inter-thread communication
10  * (where one side writes and the other reads), the code>Exchanger relies on a single
11  * exchange method for the transfer of one-off data between threads. The Exchanger is
12  * not a general replacement for the piped model, but their usages are similar.
13  *
14  * To exchange objects, you call the exchange method. The method transfers objects in both
15  * directions, not just one.
16  *  
17  * An Exchanger is often used when you have two threads, one consuming a resource,
18  * and the other producing it. When the buffer used by the producer is full, the
19  * producer waits for the consumer. When the buffer used by the consumer is empty,
20  * the consumer waits for the producer. After both waits happen, the two threads swap
21  * buffers. This works well when you know more items will be produced. Otherwise,
22  * items will sit waiting for a full buffer before swapping buffers.
23  *
24  * Here's an example that uses the Exchanger. The FillingLoop class is the producer
25  * type. The EmptyingLoop class is the consumer. When the producer's data structure
26  * is full, it tries to exchange with the consumer. When the consumer's data structure
27  * is empty, it tries to exchange data structures with the producer. After both the
28  * producer and consumer are waiting, the exchange happens.
29  */
30  
31 public class ExchangerTest {  
32  
33   private static final int FULL = 10;
34   private static final int COUNT = FULL * 20;
35   private static final Random random = new Random();
36   private static volatile int sum = 0;
37  
38   private static Exchanger<List<Integer>> exchanger =
39     new Exchanger<List<Integer>>();
40  
41   private static List<Integer> initiallyEmptyBuffer;
42   private static List<Integer> initiallyFullBuffer;
43   private static CountDownLatch stopLatch =
44     new CountDownLatch(2);  
45  
46   private static class FillingLoop implements Runnable {
47     public void run() {
48       List<Integer> currentBuffer = initiallyEmptyBuffer;
49       try {
50         for (int i = 0; i < COUNT; i++) {
51           if (currentBuffer == null)
52             break; // stop on null
53           Integer item = random.nextInt(100);
54           System.out.println("Added: " + item);
55           currentBuffer.add(item);
56           if (currentBuffer.size() == FULL)
57             currentBuffer =
58               exchanger.exchange(currentBuffer);
59         }
60       } catch (InterruptedException ex) {
61         System.out.println("Bad exchange on filling side");
62       }
63       stopLatch.countDown();
64     }
65   }  
66  
67   private static class EmptyingLoop implements Runnable {
68     public void run() {
69       List<Integer> currentBuffer = initiallyFullBuffer;
70       try {
71         for (int i = 0; i < COUNT; i++) {
72           if (currentBuffer == null)
73             break; // stop on null
74           Integer item = currentBuffer.remove(0);
75           System.out.println("Got: " + item);
76           sum += item.intValue();
77           if (currentBuffer.isEmpty()) {
78             currentBuffer =
79                exchanger.exchange(currentBuffer);
80           }
81         }
82       } catch (InterruptedException ex) {
83         System.out.println("Bad exchange on emptying side");
84       }
85       stopLatch.countDown();
86     }
87   }  
88  
89   public static void main(String args[]) {
90  
91     initiallyEmptyBuffer = new ArrayList<Integer>();
92     initiallyFullBuffer = new ArrayList<Integer>(FULL);
93  
94     for (int i=0; i<FULL; i++) {
95       initiallyFullBuffer.add(random.nextInt(100));
96     }
97  
98     new Thread(new FillingLoop()).start();
99     new Thread(new EmptyingLoop()).start();
100  
101     try {
102       stopLatch.await();
103     } catch (InterruptedException ex) {
104         ex.printStackTrace();
105     }
106  
107     System.out.println("Sum of all items is.... " + sum);
108   }
109 }