java并发库java.util.concurrent各类的使用示例

来源:互联网 发布:顾客数据 编辑:程序博客网 时间:2024/06/15 20:50
  1. Executor
package concurrent.executor;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.Executor;import java.util.concurrent.Executors;/** * Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。 * public static ExecutorService newFixedThreadPool(int nThreads) * 创建固定数目线程的线程池。 * public static ExecutorService newCachedThreadPool() * 创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。 * public static ExecutorService newSingleThreadExecutor() * 创建一个单线程化的Executor。 * public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) * @author xiaoyang * */public class TaskExecutorWebServer {private static final Executor exec=Executors.newFixedThreadPool(100);public static void main(String[] args) throws Exception {ServerSocket ss=new ServerSocket(8888);while(true){    finalSocket connection= ss.accept();    Runnable task=new Runnable() {@Overridepublic void run() {//handleRequest(connection);}};exec.execute(task);}}}
<span style="font-size: 24px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">Executorservice</span>
package concurrent.executorservice;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * ExecutorService扩展了Executor并添加了一些生命周期管理的方法。一个Executor的生命周期有三种状态,运行 ,关闭 ,终止 。Executor创建时处于运行状态。当调用ExecutorService.shutdown()后,处于关闭状态,isShutdown()方法返回true。这时,不应该再想Executor中添加任务,所有已添加的任务执行完毕后,Executor处于终止状态,isTerminated()返回true。 *如果Executor处于关闭状态,往Executor提交任务会抛出unchecked exception RejectedExecutionException。 * @author xiaoyang * */public class LifecycleWebServer {private  final ExecutorService exec=Executors.newFixedThreadPool(100);public  void start() throws Exception {ServerSocket ss=new ServerSocket(8888);while(!exec.isShutdown()){    finalSocket connection= ss.accept();    Runnable task=new Runnable() {@Overridepublic void run() {//handleRequest(connection);}};exec.execute(task);}}public void stop(){exec.shutdown();}}

package concurrent.executorservice;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/** * Future<V>代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞。FutureTask<V>实现了Future<V>和Runable<V>。Callable代表一个有返回值得操作。 * @author xiaoyang */public class CallableLifecycleWebServer {private  final ExecutorService exec=Executors.newFixedThreadPool(100);public  void start() throws Exception {ServerSocket ss=new ServerSocket(8888);while(!exec.isShutdown()){    finalSocket connection= ss.accept();    Callable<Object> task=new Callable<Object>() {@Overridepublic Object call() {//return handleRequest(connection);return null;}};Future<Object> f= exec.submit(task);Object result= f.get();}}public void stop(){exec.shutdown();}}

ExecutorThreadPool
package concurrent.ExecutorThreadPool;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)   *corePoolSize:池中所保存的线程数,包括空闲线程(非最大同时干活的线程数)。如果池中线程数多于 corePoolSize,则这些多出的线程在空闲时间超过 keepAliveTime 时将会终止。  *maximumPoolSize:线程池中最大线程数  *keepAliveTime:线程空闲回收的时间  *unit:keepAliveTime的单位  *workQueue:保存任务的队列,可以如下选择:  * •  无界队列: new LinkedBlockingQueue<Runnable>(); * •  有界队列: new ArrayBlockingQueue<Runnable>(8);你不想让客户端无限的请求吃光你的CPU和内存吧,那就用有界队列  *handler:当提交任务数大于队列size会抛出RejectedExecutionException,可选的值为:  * •ThreadPoolExecutor.CallerRunsPolicy 等待队列空闲 *•ThreadPoolExecutor.DiscardPolicy:丢弃要插入队列的任务 *•ThreadPoolExecutor.DiscardOldestPolicy:删除队头的任务 *  * @author xiaoyang * */public class ExecutorThreadPoolDemo_ {public static void main(String[] args) {BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.DAYS, queue);for (int i = 0; i < 20; i++) {final int index = i;executor.submit(new Runnable() {public void run() {try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(String.format("thread %d finished", index));}});}executor.shutdown();}}

SchedualExecutorService
package concurrent.schedual_executor_service;import java.util.concurrent.Callable;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.ScheduledFuture;import java.util.concurrent.TimeUnit;/** * ScheduledExecutorService接口 *在ExecutorService的基础上,ScheduledExecutorService提供了按时间安排执行任务的功能,它提供的方法主要有: *•schedule(task,initDelay):安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。 *•scheduleAtFixedRate():安排所提交的Runnable任务按指定的间隔重复执行 *•scheduleWithFixedDelay():安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。  *@author xiaoyang*/public class ScheduledExecutorServiceTest {private static final ScheduledExecutorService service=Executors.newScheduledThreadPool(2);public static void main(String[] args) throws Exception {Runnable task1=new Runnable() {@Overridepublic void run() {System.out.println("task1 running ");}};@SuppressWarnings("rawtypes")final ScheduledFuture future1=service.scheduleAtFixedRate(task1, 1, 10, TimeUnit.SECONDS);final ScheduledFuture<String> future2=service.schedule(new Callable<String>() {@Overridepublic String  call() throws Exception {  future1.cancel(true);                  return "task1 cancelled!";}}, 20, TimeUnit.SECONDS);System.out.println(future2.get());service.shutdown();}}

CompletionService
package concurrent.CompletionService;import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.Callable;import java.util.concurrent.CompletionService;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorCompletionService;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.LinkedBlockingQueue;/** * @author xiaoyang * */public class CompletionServiceTest {public static void main(String[] args) throws Exception {CompletionServiceTest t = new CompletionServiceTest();t.count1();t.count2();}//使用阻塞容器保存每次Executor处理的结果,在后面进行统一处理public void count1() throws Exception{long time1=System.currentTimeMillis();ExecutorService exec = Executors.newCachedThreadPool();BlockingQueue<Future<Integer>> queue = new LinkedBlockingQueue<Future<Integer>>();for(int i=0; i<100; i++){Future<Integer> future =exec.submit(getTask());queue.add(future);}int sum = 0;int queueSize = queue.size();for(int i=0; i<queueSize; i++){sum += queue.take().get();}long time2=System.currentTimeMillis();System.out.println("总数为:"+sum);System.out.println("共耗时:"+(time2-time1));exec.shutdown();}//使用CompletionService(完成服务)保持Executor处理的结果public void count2() throws InterruptedException, ExecutionException{long time1=System.currentTimeMillis();ExecutorService exec = Executors.newCachedThreadPool();CompletionService<Integer> execcomp = new ExecutorCompletionService<Integer>(exec);for(int i=0; i<100; i++){execcomp.submit(getTask());}int sum = 0;for(int i=0; i<100; i++){//检索并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则等待。Future<Integer> future = execcomp.take();sum += future.get();}long time2=System.currentTimeMillis();System.out.println("总数为:"+sum);System.out.println("共耗时:"+(time2-time1));exec.shutdown();}//得到一个任务public Callable<Integer> getTask(){final Random rand = new Random();Callable<Integer> task = new Callable<Integer>(){@Overridepublic Integer call() throws Exception {int i = rand.nextInt(10);int j = rand.nextInt(10);int sum = i*j;System.out.print(sum+"\t");return sum;}};return task;}}

CountDownLatch
package concurrent.CountDownLatch;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/* * 从名字可以看出,CountDownLatch是一个倒数计数的锁,当倒数到0时触发事件,也就是开锁,其他人就可以进入了。 * 在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。  * CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。 * 一个CountDouwnLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。 * 下面的例子简单的说明了CountDownLatch的使用方法,模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。 * */public class CountDownLatchTest {public static void main(String[] args) throws InterruptedException {// 开始的倒数锁final CountDownLatch begin = new CountDownLatch(1);// 结束的倒数锁final CountDownLatch end = new CountDownLatch(10);// 十名选手final ExecutorService exec = Executors.newFixedThreadPool(10);for (int index = 0; index < 10; index++) {final int NO = index + 1;Runnable run = new Runnable() {public void run() {try {begin.await();Thread.sleep((long) (Math.random() * 10000));System.out.println("No." + NO + " arrived");} catch (InterruptedException e) {} finally {end.countDown();}}};exec.submit(run);}System.out.println("Game Start");begin.countDown();end.await();System.out.println("Game Over");exec.shutdown();}}

CyclicBarrier
package concurrent.CyclicBarrier;import java.io.IOException;import java.util.Random;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * CyclicBarrier类似于CountDownLatch也是个计数器, * 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, * 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 * CyclicBarrier就象它名字的意思一样,可看成是个障碍, * 所有的线程必须到齐后才能一起通过这个障碍。 * CyclicBarrier初始时还可带一个Runnable的参数, * 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。 */class Runner implements Runnable {private CyclicBarrier barrier;private String name;public Runner(CyclicBarrier barrier, String name) {super();this.barrier = barrier;this.name = name;}@Overridepublic void run() {try {Thread.sleep(1000 * (new Random()).nextInt(8));System.out.println(name + " 准备OK.");barrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}System.out.println(name + " Go!!");}}public class Race {public static void main(String[] args) throws IOException, InterruptedException {CyclicBarrier barrier = new CyclicBarrier(3);ExecutorService executor = Executors.newFixedThreadPool(3);executor.submit(new Thread(new Runner(barrier, "zhangsan")));executor.submit(new Thread(new Runner(barrier, "lisi")));executor.submit(new Thread(new Runner(barrier, "wangwu")));executor.shutdown();}}

Semaphore
package concurrent.Semaphore;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;/** *  Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念, *  在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制, *  Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可, *  如果没有就等待,而 release() 释放一个许可。 *  比如在Windows下可以设置共享文件的最大客户端访问个数。  *   *  Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所, *  那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用, *  当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。 *  另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。 * */public class SemaphoreSample {public static void main(String[] args) {        // 线程池        ExecutorService exec = Executors.newCachedThreadPool();        // 只能5个线程同时访问        final Semaphore semp = new Semaphore(5);         // 模拟20个客户端访问         for (int index = 0; index < 20; index++) {              final int NO = index;              Runnable run = new Runnable() {                 public void run() {                            try {                                    // 获取许可                                    semp.acquire();                                    System.out.println("Accessing: " + NO);                                    Thread.sleep((long) (Math.random() * 10000));                                    // 访问完后,释放                                    semp.release();                                    System.out.println("-----------------"+semp.availablePermits());                            } catch (InterruptedException e) {                                    e.printStackTrace();                            }                  }              };              exec.execute(run);     }     // 退出线程池     exec.shutdown();}}

Exchanger
package concurrent.Exchanger;import java.util.concurrent.Exchanger;/** * 类java.util.concurrent.Exchanger提供了一个同步点, 在这个同步点,一对线程可以交换数据。 * 每个线程通过exchange()方法的入口提供数据给他的伙伴线程, 并接收他的伙伴线程提供的数据,并返回。 当两个线程通过Exchanger交换了对象, * 这个交换对于两个线程来说都是安全的。 */public class ExchangerSample {public static void main(String args[]) {Exchanger<String> exgr = new Exchanger<String>();new UseString(exgr);new MakeString(exgr);}}class MakeString implements Runnable {Exchanger<String> ex;String str;MakeString(Exchanger<String> c) {ex = c;str = new String();new Thread(this).start();}public void run() {char ch = 'A';for (int i = 0; i < 3; i++) {for (int j = 0; j < 5; j++)str += (char) ch++;try {str = ex.exchange(str);} catch (InterruptedException exc) {System.out.println(exc);}}}}class UseString implements Runnable {Exchanger<String> ex;String str;UseString(Exchanger<String> c) {ex = c;new Thread(this).start();}public void run() {for (int i = 0; i < 3; i++) {try {str = ex.exchange(new String());System.out.println("Got: " + str);} catch (InterruptedException exc) {System.out.println(exc);}}}}

ReentranLock  Condition

package concurrent.reentranLock_condition;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** *  java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象, *  它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。 *  这就为 Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。 *  ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义, *  但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。 *  此外,它还提供了在激烈争用情况下更佳的性能。 *  (换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。)*   reentrant 锁意味着什么呢?简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,*   那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放。这模仿了 synchronized 的语义;*   如果线程进入由线程已经拥有的监控器保护的 synchronized 块,就允许线程继续进行,*   当线程退出第二个(或者后续) synchronized 块的时候,不释放锁,只有线程退出它进入的监控器保护的第一个 synchronized 块时,才释放锁。 */public class ProductQueue<T> {    private final T[] items;    private final Lock lock = new ReentrantLock();    private Condition notFull = lock.newCondition();    private Condition notEmpty = lock.newCondition();    private int head, tail, count;    public ProductQueue(int maxSize) {        items = (T[]) new Object[maxSize];    }    public ProductQueue() {        this(10);    }    public void put(T t) throws InterruptedException {        lock.lock();        try {            while (count == getCapacity()) {                notFull.await();            }            items[tail] = t;            if (++tail == getCapacity()) {                tail = 0;            }            ++count;            notEmpty.signalAll();        } finally {            lock.unlock();        }    }    public T take() throws InterruptedException {        lock.lock();        try {            while (count == 0) {                notEmpty.await();            }            T ret = items[head];            items[head] = null;//GC            //            if (++head == getCapacity()) {                head = 0;            }            --count;            notFull.signalAll();            return ret;        } finally {            lock.unlock();        }    }    public int getCapacity() {        return items.length;    }    public int size() {        lock.lock();        try {            return count;        } finally {            lock.unlock();        }    }}

package concurrent.reentranLock_condition;import java.util.HashSet;import java.util.Set;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class TestCondition  {static final CountDownLatch cdl = new CountDownLatch(31);public static void main(String[] args) {Monitor monitor = new Monitor();ExecutorService executorService = Executors.newFixedThreadPool(31);for (int i = 0; i < 30; i++) {Student student = new Student(monitor);monitor.addClassMate(student);executorService.execute(student);}executorService.execute(monitor);System.out.println(Thread.currentThread() + "老师还没来");monitor.setTeacherIsComing(true);System.out.println(Thread.currentThread() + "老师来了");try {cdl.await();} catch (InterruptedException e) {e.printStackTrace();}executorService.shutdown();}static class Student implements Runnable {private Monitor monitor;Student() {}Student(Monitor monitor) {this.monitor = monitor;}@Overridepublic void run() {try {monitor.getLock().lock();while (!monitor.isTeacherIsComing()) {monitor.getCondition().await();}} catch (InterruptedException e) {e.printStackTrace();} finally {monitor.getLock().unlock();cdl.countDown();}System.out.println(Thread.currentThread() + "回到自己座位,坐下");}}static class Monitor extends Student {private boolean teacherIsComing = false;private Set<Student> classMates = new HashSet<Student>();private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();@Overridepublic void run() {lock.lock();while (!teacherIsComing) {System.out.println(Thread.currentThread() + "看老师是否来了");}condition.signalAll();lock.unlock();cdl.countDown();}public boolean isTeacherIsComing() {return teacherIsComing;}public void setTeacherIsComing(boolean teacherIsComing) {this.teacherIsComing = teacherIsComing;}public void addClassMate(Student student) {classMates.add(student);}public Condition getCondition() {return condition;}public Lock getLock() {return lock;}}}

BlockingQueue

package concurrent.blockingQueue.demo;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class TestBlockingQueues {    public static void main(String[] args) {        BlockingQueue<String> queue = new ArrayBlockingQueue<String>(20);        for (int i = 0; i < 10; i++) {            Thread pro = new Thread(new Producer(queue), "生产者" + i);            pro.start();        }        for (int i = 0; i < 10; i++) {            Thread t = new Thread(new Concumer(queue), "消费者 " + i);            t.start();        }    }}class Producer implements Runnable {    BlockingQueue<String> queue;    public Producer(BlockingQueue<String> queue) {        this.queue = queue;    }    @Override    public void run() {        int i = 0;        while (true) {            try {                                   System.out.println(Thread.currentThread().getName()                            + "生产食物, 食物编号为:" + Thread.currentThread().getName()                            + i);                    queue.put(" 食物 " + Thread.currentThread().getName() + i++);                    Thread.sleep(10000);                           } catch (InterruptedException e) {                System.out.println("生产者被中断");            }        }    }}class Concumer implements Runnable {    BlockingQueue<String> queue;    public Concumer(BlockingQueue<String> queue) {        this.queue = queue;    }    @Override    public void run() {        while (true) {            System.out.println(Thread.currentThread().getName() + " 请求消费");            try {                System.out.println(Thread.currentThread().getName() + "消费:"                        + queue.take());                Thread.sleep(100);            } catch (InterruptedException e) {                System.out.println("消费者被中断");            }        }    }}



0 0
原创粉丝点击