java中并发工具包(上)

一、并发工具包简介

  • 传统的多线程并没有提供高级特性,例如:信号量、线程池和执行管理器等,而这些特性恰恰有助于创建强大的并发程序。新的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();
            }
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值