A concept
Exchanger can exchange objects between the two threads driven tasks. Before switching, A task holds objects D1, B task holds D2 objects. After the exchange, A task holds objects D2, B task holds D1 object.
Exchanger can use scenarios:
1. The large amount of data, multi-step tasks performed
For example, the entire task became divided n segments. The first task processing scripts to some extent upon execution, perform Exchanger exchange () operation, the data has been transmitted to the second processed piece task, each task is driven by a different thread, to speed up the overall tasks speed.
2. Genetic Algorithms
II. Use
1. Exchanger( )
Constructor, create a new Exchanger objects
/**
* Creates a new Exchanger.
*/
public Exchanger() {
participant = new Participant();
}
2. exchange(V x)
Interchangeable objects. Two tasks must call exchange () swap to be successful. When a task calls the exchange Exchanger object (), it will be to block until another task also called exchange objects of the same Exchanger () method, then swap the x object operation will be successful .
III. Case
This example creates a producer and consumer, producer production Fat objects, consumer spending Fat objects, with Exchanger between objects, swap List <Fat> collection.
1. Producer
private Generator<T> generator;
private Exchanger<List<T>> exchanger;
private List<T> holder;
public ExchangerProducer(Exchanger<List<T>> exchanger, Generator<T> gen, List<T> holder) {
this.exchanger = exchanger;
this.generator = gen;
this.holder = holder;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
for(int i = 0; i < ExchangerDemo.size; i++) {
holder.add(generator.next());
}
holder = exchanger.exchange(holder);
}
} catch (InterruptedException e) {
System.out.println("OK to terminate this way");
}
}
}
2. Consumers
class ExchangerConsumer<T> implements Runnable {
private Exchanger<List<T>> exchanger;
private List<T> holder;
private volatile T value;
public ExchangerConsumer(Exchanger<List<T>> exchanger, List<T> holder) {
this.exchanger = exchanger;
this.holder = holder;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
holder = exchanger.exchange(holder);
for (T x : holder) {
// 此处在遍历列表时,移除了元素。为了不报错ConcurrentModificationException,
// 所以使用CopyOnWriteArrayList
value = x;
holder.remove(x);
}
}
}catch (InterruptedException e) {
System.out.println("OK to terminate this way");
}
System.out.println("Final value: " + value);
}
}
3. main method
public class ExchangerDemo {
static int size = 10;
static int delay = 5;
public static void main(String[] args) throws Exception{
if(args.length > 0) {
size = Integer.parseInt(args[0]);
}
if(args.length > 1) {
delay = Integer.parseInt(args[1]);
}
ExecutorService exec = Executors.newCachedThreadPool();
Exchanger<List<Fat>> xc = new Exchanger<>();
List<Fat> producerList = new CopyOnWriteArrayList<>();
List<Fat> consumerList = new CopyOnWriteArrayList<>();
exec.execute(new ExchangerProducer<>(xc, BasicGenerator.create(Fat.class), producerList));
exec.execute(new ExchangerConsumer<>(xc, consumerList));
TimeUnit.SECONDS.sleep(delay);
exec.shutdownNow();
}
}
4. Perform results
OK to terminate this way
Final value: Fat id:90189
OK to terminate this way