標籤:多線程 並發 exchanger
package org.rui.thread.newc;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;import org.rui.generics.anonymity.BasicGenerator;import org.rui.generics.anonymity.Generator;import org.rui.thread.newc.semaphore.Fat;/** * @author lenovo * 在兩個任務之間切換柵欄,當這些柵欄進入任務時,它們和自擁有一個對象,當它們離開時,它們都擁有之前由對象持有的對象。 * * == * 可以有更多的對象在被建立的同時被消費。 * *//** * 生產者 */class ExchangerProduer<T> implements Runnable{private Generator<T> generator;// 產生器private Exchanger<List<T>> exchanger;private List<T> holder;// 對象集合ExchangerProduer(Exchanger<List<T>> exchg, Generator<T> generator,List<T> holder){this.generator = generator;this.exchanger = exchg;this.holder = holder;}@Overridepublic void run(){try{while (!Thread.interrupted()){for (int i = 0; i < ExchangerDemo.size; i++){// 把加工好的對象放入集合中T t = generator.next();System.err.println(Thread.currentThread().getName()+ ">>生產對象:" + t);holder.add(generator.next());/** * exchange(V v) * 等待另一個線程到達此交換點(除非當前線程被中斷),然後將給定的對象傳送給該線程,並接收該線程的對象。 */// exchange full for empty: 全部為空白holder = exchanger.exchange(holder);}}} catch (InterruptedException e){// ok to terminate this way 可以以這種方式終止}}}/** * demo main * @author lenovo * * @param <T> */class ExchangerConsumer<T> implements Runnable{private Exchanger<List<T>> exchanger;private List<T> holder;private volatile T value;ExchangerConsumer(Exchanger<List<T>> ex, List<T> holder){exchanger = ex;this.holder = holder;}@Overridepublic void run(){try{while (!Thread.interrupted()){// 消費者取出對象 進行處理exchanger.exchange(holder);for (T x : holder){value = x;// fetch out valueSystem.out.println(Thread.currentThread().getName()+ "消費對象:" + x);holder.remove(x);// ok for copyOmWriteArrayList 消費完成移除}}} catch (InterruptedException e){// ok to terminate this way}System.out.println("Final value:" + value);}}public class ExchangerDemo{static int size = 10;static int delay = 5;public static void main(String[] args) throws Exception{String[] argss = new String[]{ "10", "5" };if (argss.length > 0){size = new Integer(argss[0]);}if (argss.length > 1){delay = new Integer(argss[0]);}ExecutorService exec = Executors.newCachedThreadPool();Exchanger<List<Fat>> xc = new Exchanger<List<Fat>>();// ----------------------生產者// CopyOnWriteArrayList >>>ArrayList 的一個安全執行緒的變體,// 其中所有可變操作(add、set 等等)都是通過對底層數組進行一次新的複製來實現的List<Fat> producerList = new CopyOnWriteArrayList<Fat>();ExchangerProduer produer = new ExchangerProduer<Fat>(xc,BasicGenerator.create(Fat.class), producerList);//當調用 exchange(), 它將阻塞直至對方任務調用它自已的exchange()方法,那時,兩個exchange()方法將全部完成,而List<T>則被互轉:exec.execute(produer);TimeUnit.SECONDS.sleep(delay);// ---------------------- 消費 List<Fat> consumerList = new CopyOnWriteArrayList<Fat>();// 消費者exec.execute(new ExchangerConsumer<Fat>(xc, consumerList));TimeUnit.SECONDS.sleep(delay);// 試圖停止所有正在執行的活動任務,暫停處理正在等待的任務,並返回等待執行的工作清單。exec.shutdownNow();}}/** * output: * Final value:Fat>>id:89024 */
相關輔助類
//Generator.javapackage org.rui.generics.anonymity;public interface Generator<T> {// 返回泛型的內型對象T next();}
-----------
package org.rui.generics.anonymity;public class BasicGenerator<T> implements Generator<T>{private Class<T> type;public BasicGenerator(Class<T> type){this.type = type;}@Overridepublic T next(){try{return type.newInstance();} catch (Exception e){throw new RuntimeException(e);}}public static <T> Generator<T> create(Class<T> type){return new BasicGenerator<T>(type);}}
package org.rui.thread.newc.semaphore;public class Fat{private volatile double d;private static int counter = 0;private final int id = counter++;public Fat(){// expensive, interruptible operation:for (int i = 1; i < 10000; i++){d += (Math.PI + Math.E) / (double) i;}}public void operation(){System.out.println("operation>> "+this);}@Overridepublic String toString(){return "Fat>>id:" + id;}}
java多線程並發——Exchanger 兩個任務之間交換對象