java中并发工具包(上)

来源:互联网 发布:js京东购物车代码 编辑:程序博客网 时间:2024/04/26 18:08

一、并发工具包简介

  • 传统的多线程并没有提供高级特性,例如:信号量、线程池和执行管理器等,而这些特性恰恰有助于创建强大的并发程序。新的Fork/Join框架针对当前的多核系统,也提供了并行编程的可能。
  • 体系结构:
    (1)java拧发工具包处于java.util.concurrent包中;
    (2)主要包括同步器、执行器、并发集合、Fork/Join框架、atomic包、locks包。
    (3)
    • 同步器:为每种特定的同步问题提供了解决方案;
    • 执行器:用来管理线程的执行,典型应用是线程池;
    • 并发集合:提供了集合框架中集合的并发版本;
    • Fork/Join框架:提供了对并行编程的支持;
    • atomic包:提供了不需要锁即可完成并发环境变量使用的原子性操作;
    • locks包:使用Lock接口为并发编程提供了同步的另外一种替代方案。

二、同步器Semaphore、CountDownLatch同步器、CyclicBarrier同步器、Exchanger同步器、Phaser同步器

  1. Semaphore同步器(信号量)
    (1)Semaphore同步器简介:描述了一个在操作系统当中比较经典的信号量,主要作用是通过计数器来控制对共享资源的访问。
    常用API
    • Semaphore(int count):创建拥有count个许可证的信号量。
    • acquire()/acquire(int num):获取1/num个许可证
    • release()/release(int num):释放1/num个许可证
import java.util.concurrent.Semaphore;public class SeDemo {    public static void main(String[] args){        //创建信号量许可证,指定允许最多几个并发线程能够进入        Semaphore semaphore = new Semaphore(2);        Person p1 = new Person(semaphore, "A");        p1.start();        Person p2 = new Person(semaphore, "B");        p2.start();        Person p3 = new Person(semaphore, "C");        p3.start();    }}class Person extends Thread {    private Semaphore semaphore;    public Person(Semaphore semaphore,String name){        setName(name);        this.semaphore = semaphore;    }    @Override    public void run() {        // TODO Auto-generated method stub        System.out.println(getName()+"is waiting....");        try {            //获取许可证            semaphore.acquire();            System.out.println(getName()+"is servicing....");            Thread.sleep(1000);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println(getName()+"is done!");        //释放许可证        semaphore.release();    }}
  1. CountDownLatch同步器(计数栓)
    (1) CountDownLatch简介:典型特征是必须发生指定数量的事件后才可以继续运行。
    常用API:
    • CountDownLatch(int count):必须发生count个数量事件才可以打开锁存器
    • await():等待锁存器
    • countDown():触发事件
import java.util.concurrent.CountDownLatch;public class CDDemo {    public static void main(String[] args){        //创建计数栓对象,设置计数栓需要触发的事件数        CountDownLatch countDownLatch = new CountDownLatch(3);        new Racer(countDownLatch, "A").start();        new Racer(countDownLatch, "B").start();        new Racer(countDownLatch, "C").start();        for(int i=0;i<3;i++){            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            System.out.println(3-i);            countDownLatch.countDown();//该计数栓对象计数一次,当运行3次时设置该计数栓的线程开始运行            if(i==2){                System.out.println("Start");            }        }    }}class Racer extends Thread {    private CountDownLatch countDownLatch;    public Racer(CountDownLatch countDownLatch,String name){        setName(name);        this.countDownLatch = countDownLatch;    }    public void run(){        try {            countDownLatch.await();//等待计数栓完成指定数量的计数            for(int i=0;i<3;i++){                System.out.println(getName()+":"+i);            }        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
  1. CyclicBarrier同步器
    (1) 适用于只有多个线程都到达预定点时才可以继续执行
    常用API:
    • CyclicBarrier(int num);等待线程的数量
    • CyclicBarrier(int num, Runnable action):等待线程的数量以及所有线程到达后的操作
    • await():到达临界点后暂停线程
import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class CBDemo {    public static void main(String[] args){        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable(){            @Override            public void run() {                // TODO Auto-generated method stub                System.out.println("Game start");            }        });        new Player(cyclicBarrier,"A").start();        new Player(cyclicBarrier,"B").start();        new Player(cyclicBarrier,"C").start();    }}class Player extends Thread {    private CyclicBarrier cyclicBarrier;    public Player(CyclicBarrier cyclicBarrier,String name){        setName(name);        this.cyclicBarrier = cyclicBarrier;    }    public void run(){        System.out.println(getName()+" is waitting other players...");        try {            cyclicBarrier.await();        } catch (InterruptedException | BrokenBarrierException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
  1. Exchanger同步器
    (1) 简化两个线程间数据的交换
    常用API:
    • Exchanger:指定进行交换的数据类型
    • V exchange(V object):等待线程到达,交换数据。
import java.util.concurrent.Exchanger;public class EDemo {    public static void main(String[] args){        Exchanger ex =new Exchanger<String>();        new A(ex).start();        new B(ex).start();    }}class A extends Thread {    private Exchanger<String> ex;    public A(Exchanger<String> ex){        this.ex = ex;    }    public void run(){        String str = null;        try {            str = ex.exchange("Hello");            System.out.println(str);            str = ex.exchange("A");            System.out.println(str);            str = ex.exchange("B");            System.out.println(str);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}class B extends Thread {    private Exchanger<String> ex;    public B(Exchanger<String> ex){        this.ex = ex;    }    public void run(){        String str = null;        try {            str = ex.exchange("Hi");            System.out.println(str);            str = ex.exchange("1");            System.out.println(str);            str = ex.exchange("2");            System.out.println(str);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
  1. Phaser同步器
    (1) 工作方式与CyclicBarrier类似,但是可以定义多个阶段
    常用API:
    • Phaser()/Phaser(int num):使用指定0/num个party创建Phaser
    • register():注册party
    • arriveAndAdvance():到达时等待所有party到达
    • arriveAndDeregister():到达时注销线程自己
import java.util.concurrent.Phaser;public class PDemo {    public static void main(String[] args){        Phaser phaser = new Phaser(1);        System.out.println("starting...");        new Worker(phaser,"服务员").start();        new Worker(phaser,"厨师").start();        new Worker(phaser,"上菜员").start();        for(int i=1;i<=3;i++){            phaser.arriveAndAwaitAdvance();            System.out.println("Order "+i+" finished!");        }        phaser.arriveAndDeregister();        System.out.println("ALL DONE!");    }}class Worker extends Thread {    private Phaser phaser;    public Worker(Phaser phaser, String name){        this.setName(name);        this.phaser = phaser;        phaser.register();    }    public void run(){        for(int i=1;i<=3;i++){            System.out.println("current order is :"+i+":"+getName());            if(i==3){                phaser.arriveAndDeregister();            }else{                phaser.arriveAndAwaitAdvance();            }            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}
0 0
原创粉丝点击