併發工具概述
體系結構
A.併發工具處於java.util.concurrent包
B.其實包括的內容有:
-同步器
-執行器
-併發集合
-Fork/join框架
-atomic包
-locks包
各組成部分和作用
同步器:爲各種特定的同步問題提供瞭解決方案
執行器:用來管理線程的執行
併發集合:提供了集合框架中集合的併發版本
Fork/Join框架:提供了對併發編程的支持
atomic包:提供了不需要鎖即可完成併發環境變量使用的原子性操作
locks包:使用lock接口爲併發編程提供了同步的另一種替代方案
同步器Semaphore 和 CountDownLatch API介紹和代碼實現
同步器 Semaphore(信號量)
Semaphore - API
Semaphpre - 演示代碼
package com.semaphore.demo1;
import java.util.concurrent.Semaphore;
/**
* 主函數 - 類
*
*演示目標:模擬銀行窗口服務流程
*
* 條件: 1.有兩個服務窗口
* 2.三名顧客在等待服務
* 代碼實現
* */
public class DemoCase {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
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();
}
}
Semaphpre - 運行結果
Semaphpre - 使用總結
Semaphore 同步器運行特性:
1.可以自定義同時併發的線程數量。
如:線程數量爲3,但設置信號量爲2,就會先併發執行兩條線程,然後執行第3條線程。
2.併發執行線程的順序是隨機的,也就是說沒有固定順序。
Semaphore API應用及其運行步驟
1.功能類 書寫步驟
1. - semaphore.acquire();
2. - 功能實現部分
3. - semaphore.release();
2.調用類 書寫步驟
1. -Semaphore semaphore = new Semaphore(2);
2.Person p1 = new Person(semaphore, "A");
p1.start();
CountDownLatch(計數栓)
CountDownLatch - API
CountDownLatch - 演示代碼
package com.countdownlatch.demo1;
import java.util.concurrent.CountDownLatch;
/**
* 主函數 - 類
*
* 演示目標:模擬賽跑比賽,裁判員倒數3,2,1之後,所有線程併發執行
*
* 演示代碼
* */
public class DemoCase {
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);
System.out.println(3-i);
if(i ==2 )
{
System.out.println("開始起跑");
}
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 功能 - 類
*
* */
class Racer extends Thread
{
private CountDownLatch countDownLatch;
public Racer(CountDownLatch countDownLatch,String name) {
setName(name);
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
countDownLatch.await();
for (int i = 0; i < 3; i++) {
System.out.println(getName()+": "+i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}
CountDownLatch - 運行結果
CountDownLatch - 使用總結
CountDownLatch 同步器運行特性:
1.可以自定義線程運行的時間
2.同樣線程的先後執行順序也是無序的,隨機執行。
CountDownLatch API的應用以及書寫方式
功能類:完成需求功能即可。
調用類:CountDownLatch countDownLatch = new CountDownLatch(3);
countDownLatch.countDown();
同步器- CyclicBarrier、Exchanger 和 Phaser API介紹和代碼實現
同步器- CyclicBarrier(關卡)
CyclicBarrier - API
CyclicBarrier - 演示代碼
package com.CyclicBarrier.demo1;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class DemoCase {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3,new Runnable() {
@Override
public void run() {
System.out.println("開始 遊戲");
}
});
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;
}
@Override
public void run() {
System.out.println(getName()+" is waiting other palyers ...");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
CyclicBarrier - 運行結果
CyclicBarrier - 使用總結
CyclicBarrier 同步器特性
1.指定線程數量、以及線程都到達後執行的操作
CyclicBarrier API的應用以及書寫方式
功能類
1.在功能類書寫功能代碼,功能代碼後添加
cyclicBarrier.await();
調用類:
CyclicBarrier cyclicBarrier = new CyclicBarrier(3,new Runnable() {
@Override
public void run() {
System.out.println("開始 遊戲");
}
});
同步器 - Exchanger(交換器)
Exchanger - API
Exchanger - 演示代碼
package com.exchanger.demo1;
import java.util.concurrent.Exchanger;
public class DemoCase {
public static void main(String[] args) {
Exchanger<String> ex = new Exchanger<>();
new B(ex).start();
new A(ex).start();
}
}
class A extends Thread
{
private Exchanger<String> ex;
public A(Exchanger<String> ex) {
this.ex = ex;
}
@Override
public void run() {
String str = null ;
try {
str = ex.exchange("Hello?");
System.out.println("A的數據:"+str);
str = ex.exchange("A");
System.out.println("A的數據:"+str);
str = ex.exchange("B");
System.out.println("A的數據:"+str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class B extends Thread
{
private Exchanger<String> ex;
public B(Exchanger<String> ex) {
this.ex = ex;
}
@Override
public void run() {
String str = null ;
try {
str = ex.exchange("Hey?");
System.out.println("B的數據:"+str);
str = ex.exchange("1");
System.out.println("B的數據:"+str);
str = ex.exchange("2");
System.out.println("B的數據:"+str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Exchanger - 運行結果
Exchanger - 使用總結
Exchanger 同步器特性
1.兩條線程 數據的相互交換
Exchanger API的應用以及書寫方式
功能類
1.創建兩個線程類
2.在兩條線程類中完成功能,使用 ex.exchange("Hello?"); 準備要交換的數據
調用類:
1.Exchanger<String> ex = new Exchanger<>();
2.調用功能類即可。
同步器 - Phaser(相位器)
Phaser - API
Phaser - 演示代碼
package com.phaser.demo1;
import java.util.concurrent.Phaser;
/**
* 演示目標:模擬餐廳服務
* 條件:
* 1,有三位客人
* 2. 有三個服務環節:服務員(接待)、廚師(做菜)、傳菜(給客人上菜)
* */
public class DemoCase {
public static void main(String[] args) {
Phaser phaser = new Phaser(1);
System.out.println("準備啓動。。。");
new Worker(phaser, "服務員").start();
new Worker(phaser, "廚師").start();
new Worker(phaser, "上菜").start();
for (int i = 1; i <=3; i++) {
System.out.println(i+"號訂單開始處理");
phaser.arriveAndAwaitAdvance();
}
phaser.arriveAndDeregister();
System.out.println("All Done!");
}
}
/**
* 功能類:
* 實現了每個崗位的工作
* */
class Worker extends Thread
{
private Phaser phaser ;
public Worker(Phaser phaser ,String name)
{
setName(name);
this.phaser = phaser;
phaser.register();
}
@Override
public void run()
{
for(int i = 1; i<=3; i++)
{
System.out.println("當前服務的是:"+getName());
if(i == 3)
{
phaser.arriveAndDeregister();
}else
{
phaser.arriveAndAwaitAdvance();
}
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
Phaser - 運行結果
Phaser - 使用總結
Phaser 同步器特性
工作方式與CyclicBarrrier類似,但是可以定義多個階段
Phaser 的API的使用
1,首先在類的構造方法中先註冊 phaser.register();
2. 其次有兩種情況
當線程沒有執行完,可以等待 phaser.arriveAndAwaitAdvance();
當線程執行完,要註銷自己 phaser.arriveAndDeregister();