Java多執行緒十一 Exchanger
阿新 • • 發佈:2019-02-08
Exchanger類介紹
A synchronization point at which threads can pair and swap elements within pairs. Each thread presents some object on entry to the exchange method, matches with a partner thread, and receives its partner’s object on return. An Exchanger may be viewed as a bidirectional form of a SynchronousQueue. Exchangers may be useful in applications such as genetic algorithms and pipeline designs.
從javaDoc中我們可以總結如下幾點:
1. Exchanger是一個同步類
2. 在而且只能在兩個執行緒之間進行資料交換
3. 當一個執行緒到達exchange()呼叫點時,阻塞等待另外一個執行緒到達等待點,然後交換資料繼續各自的執行
4. 可以看做是一個雙向的同步佇列
5. 應用於基因演算法和流水線設計
示例一:
public class Consumer implements Runnable {
List<Integer> list = new ArrayList<Integer>();
Exchanger<List<Integer>> exchanger;
public Consumer(Exchanger<List<Integer>> exchanger) {
super();
this.exchanger = exchanger;
}
public void run() {
try {
while (!Thread.interrupted()) {
System.out.println("Consumer before exchager:" + this);
list = exchanger.exchange(list);
System.out.println("Consumer after exchager:" + this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (Integer value : list) {
int i = 0;
sb.append(" " + (++i) + value + " ");
}
sb.append("]");
return sb.toString();
}
}
public class Producer implements Runnable {
List<Integer> list = new ArrayList<Integer>();
Exchanger<List<Integer>> exchanger = null;
public Producer(Exchanger<List<Integer>> exchanger) {
this.exchanger = exchanger;
}
public void run() {
try {
while (!Thread.interrupted()) {
System.out.println("Producer before exchanger" + this);
Random rand = new Random();
for (int i = 0; i < 10; i++) {
list.clear();
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
list.add(rand.nextInt(10000));
}
list = exchanger.exchange(list);
System.out.println("Producer after exchanger" + this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (Integer value : list) {
int i = 0;
sb.append(" " + (++i) + value + " ");
}
sb.append("]");
return sb.toString();
}
}
public class ExchangerDemo1 {
public static void main(String[] args) throws InterruptedException {
Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(new Consumer(exchanger));
service.execute(new Producer(exchanger));
TimeUnit.SECONDS.sleep(1);
service.shutdownNow();
}
}
輸出結果如下:
Consumer after exchager:[ 1275 15315 17950 18047 13475 15804 ]
Consumer before exchager:[ 1275 15315 17950 18047 13475 15804 ]
Producer before exchanger[ 13511 12842 19060 13990 15241 18850 ]
Producer after exchanger[ 1275 15315 17950 18047 13475 15804 ]
Producer before exchanger[ 1275 15315 17950 18047 13475 15804 ]
Consumer after exchager:[ 13466 17312 1759 16423 16511 15417 ]
...