import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class ExchangerProducer implements Runnable {
private List<Fat> holder;
private Exchanger<List<Fat>> exchanger;
public ExchangerProducer(Exchanger<List<Fat>> exchanger, List<Fat> holder) {
this .exchanger = exchanger;
this .holder = holder;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
//填充列表
for ( int i = 0 ;i < ExchangerDemo.size; i++) {
holder.add( new Fat());
}
//等待交换
holder = exchanger.exchange(holder);
}
} catch (InterruptedException e) {
}
System.out.println( "Producer stopped." );
}
}
class ExchangerConsumer implements Runnable {
private List<Fat> holder;
private Exchanger<List<Fat>> exchanger;
private volatile Fat value;
private static int num = 0 ;
public ExchangerConsumer(Exchanger<List<Fat>> exchanger, List<Fat> holder) {
this .exchanger = exchanger;
this .holder = holder;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
//等待交换
holder = exchanger.exchange(holder);
//读取列表并移除元素
for (Fat x : holder) {
num++;
value = x;
//在循环内删除元素,这对于CopyOnWriteArrayList是没有问题的
holder.remove(x);
}
if (num % 10000 == 0 ) {
System.out.println( "Exchanged count=" + num);
}
}
} catch (InterruptedException e) {
}
System.out.println( "Consumer stopped. Final value: " + value);
}
}
public class ExchangerDemo {
static int size = 10 ;
static int delay = 5 ; //秒
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
List<Fat> producerList = new CopyOnWriteArrayList<>();
List<Fat> consumerList = new CopyOnWriteArrayList<>();
Exchanger<List<Fat>> exchanger = new Exchanger<>();
exec.execute( new ExchangerProducer(exchanger, producerList));
exec.execute( new ExchangerConsumer(exchanger, consumerList));
TimeUnit.SECONDS.sleep(delay);
exec.shutdownNow();
}
}
class Fat {
private volatile double d;
private static int counter = 1 ;
private final int id = counter++;
public Fat() {
//执行一段耗时的操作
for ( int i = 1 ; i< 10000 ; i++) {
d += (Math.PI + Math.E) / ( double )i;
}
}
public void print() {System.out.println( this );}
public String toString() { return "Fat id=" + id;}
}
|