一、并发工具包简介
- 传统的多线程并没有提供高级特性,例如:信号量、线程池和执行管理器等,而这些特性恰恰有助于创建强大的并发程序。新的Fork/Join框架针对当前的多核系统,也提供了并行编程的可能。
- 体系结构:
(1)java拧发工具包处于java.util.concurrent包中;
(2)主要包括同步器、执行器、并发集合、Fork/Join框架、atomic包、locks包。
(3)
- 同步器:为每种特定的同步问题提供了解决方案;
- 执行器:用来管理线程的执行,典型应用是线程池;
- 并发集合:提供了集合框架中集合的并发版本;
- Fork/Join框架:提供了对并行编程的支持;
- atomic包:提供了不需要锁即可完成并发环境变量使用的原子性操作;
- locks包:使用Lock接口为并发编程提供了同步的另外一种替代方案。
二、同步器Semaphore、CountDownLatch同步器、CyclicBarrier同步器、Exchanger同步器、Phaser同步器
- 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() {
System.out.println(getName()+"is waiting....");
try {
semaphore.acquire();
System.out.println(getName()+"is servicing....");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+"is done!");
semaphore.release();
}
}
- 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) {
e.printStackTrace();
}
System.out.println(3-i);
countDownLatch.countDown();
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) {
e.printStackTrace();
}
}
}
- 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() {
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) {
e.printStackTrace();
}
}
}
- 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) {
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) {
e.printStackTrace();
}
}
}
- 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) {
e.printStackTrace();
}
}
}
}