目錄
LockExample
package Java併發協作控制;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LockExample
{
private static final ReentrantLock queueLock = new ReentrantLock(); //可重入鎖
private static final ReentrantReadWriteLock orderLock = new ReentrantReadWriteLock();//可重入讀寫鎖
/*
* 有家奶茶店,點單時需要排隊
* 假設想買奶茶的人如果看到需要排隊,就決定不買
* 有假設奶茶店有老闆和多名員工,記單方式比較原始,只有一個訂單本
* 老闆負責寫新訂單,員工不斷的查看訂單本得到信息來製作奶茶,在老闆寫新訂單時員工不能看訂單
* 對個員工可以同時看訂單本,在員工看時老闆不能寫新訂單
*/
public static void main(String[] args) {
//buyMilkTea();
handleOrder();
}
public void tryToMilkTea() throws InterruptedException
{
boolean flag = true;
while(flag)
{
if(queueLock.tryLock())
{
long thinkingTime = (long)(Math.random()*500);
Thread.sleep(thinkingTime);
System.out.println(Thread.currentThread().getName()+", 來一杯珍珠奶茶,不要珍珠");
flag = false;
queueLock.unlock();
}
else
{
System.out.println(Thread.currentThread().getName()+"再等等");
}
if(flag)
{
Thread.sleep(1000);
}
}
}
public void addOrder() throws InterruptedException
{
orderLock.writeLock().lock();
long writingTime = (long)(Math.random()*1000);
Thread.sleep(writingTime);
System.out.println("老闆新加一筆訂單");
orderLock.writeLock().unlock();
}
public void viewOrder() throws InterruptedException
{
orderLock.readLock().lock();
long readingTime = (long)(Math.random()*1000);
Thread.sleep(readingTime);
System.out.println(Thread.currentThread().getName()+"查看訂單本");
orderLock.readLock().unlock();
}
public static void buyMilkTea()
{
LockExample lockExample = new LockExample();
int STUDENTS_CNT = 10;
Thread[] students = new Thread[STUDENTS_CNT];
for(int i=0;i<students.length;i++)
{
students[i] = new Thread(new Runnable() {
@Override
public void run() {
// TODO 自動生成的方法存根
try {
long walkingTime = (long) (Math.random()*1000);
Thread.sleep(walkingTime);
lockExample.tryToMilkTea();
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
});
students[i].start();
}
}
public static void handleOrder()
{
LockExample lockExample = new LockExample();
Thread boss = new Thread(new Runnable() {
@Override
public void run() {
// TODO 自動生成的方法存根
while(true)
{
try
{
lockExample.addOrder();
long waitingTime = (long)(Math.random()*1000);
Thread.sleep(waitingTime);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
});
boss.start();
int workerCnt = 3;
Thread[] workers = new Thread[workerCnt];
for(int i=0;i<workers.length;i++)
{
workers[i] = new Thread(new Runnable() {
@Override
public void run() {
// TODO 自動生成的方法存根
while(true)
{
try
{
lockExample.viewOrder();
long workingTime = (long)(Math.random()*1000);
Thread.sleep(workingTime);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
});
workers[i].start();
}
}
}
SemaphoreExample
package Java併發協作控制;
import java.util.concurrent.Semaphore;
public class SemaphoreExample
{
private final Semaphore placeSemaphore = new Semaphore(5);
public boolean parking()
{
if(placeSemaphore.tryAcquire())
{
System.out.println(Thread.currentThread().getName()+": 停車成功");
return true;
}else {
System.out.println(Thread.currentThread().getName()+": 沒有空位");
return false;
}
}
public void leaving()
{
placeSemaphore.release();
System.out.println(Thread.currentThread().getName()+"開走");
}
/*
* 現有一個地下車庫,共有五個停車位,有10輛車需要停放,每次停放時,去申請信號量
*/
public static void main(String[] args) {
int tryToParkCnt = 10;
SemaphoreExample semaphoreExample = new SemaphoreExample();
Thread[] parkers = new Thread[tryToParkCnt];
for(int i=0;i<parkers.length;i++)
{
parkers[i] = new Thread(new Runnable() {
@Override
public void run() {
// TODO 自動生成的方法存根
try {
long randomTime = (long)(Math.random()*1000);
Thread.sleep(randomTime);
if(semaphoreExample.parking())
{
long parkingTime = (long)(Math.random()*1000);
Thread.sleep(parkingTime);
semaphoreExample.leaving();
}
} catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
});
parkers[i].start();
}
}
}
CountDownLatchExample
package Java併發協作控制;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample
{
/*
* 設想百米賽跑比賽 發令槍發出信號後選手開始跑,全部選手跑到終點後比賽結束
*/
public static void main(String[] args) throws InterruptedException {
int runnerCnt = 10;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(runnerCnt);
for(int i=0;i<runnerCnt;i++)
{
new Thread(new Worker(startSignal,doneSignal)).start();;
}
System.out.println("準備工作...");
System.out.println("準備工作就緒");
startSignal.countDown();
System.out.println("比賽開始");
doneSignal.await();
System.out.println("比賽結束");
}
}
class Worker implements Runnable
{
private CountDownLatch startSignal;
private CountDownLatch doneSignal;
public Worker (CountDownLatch startSignal,CountDownLatch doneSignal)
{
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
@Override
public void run() {
// TODO 自動生成的方法存根
try
{
startSignal.await();
doWork();
doneSignal.countDown();
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
private void doWork() throws InterruptedException
{
long t = (long) (Math.random()*1000);
Thread.sleep(t);
System.out.println(Thread.currentThread().getName()+"用時 : "+t);
}
}
CyclicBarrierExample
package Java併發協作控制;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample
{
/*
* 假定有三行數,用三個線程分別計算每一行的和,最終計算總和
*/
public static void main(String[] args) {
final int[][] numbers = new int[3][5];
final int[] results = new int[3];
int[] row1 = new int[] {1,2,3,4,5};
int[] row2 = new int[] {6,7,8,9,10};
int[] row3 = new int[] {11,12,13,14,15};
numbers[0] = row1;
numbers[1] = row2;
numbers[2] = row3;
CalculateFinalResult finalResultCalculator = new CalculateFinalResult(results);
CyclicBarrier barrier = new CyclicBarrier(3, finalResultCalculator);
//當有三個線程在barrier上await,就執行finalResultCalculator
for(int i=0;i<3;i++)
{
CalculateEachRow rowCalculator = new CalculateEachRow(barrier,numbers,i,results);
new Thread(rowCalculator).start();
}
}
}
class CalculateEachRow implements Runnable
{
final int[][]numbers;
final int rowNumbers;
final int[] results;
final CyclicBarrier barrier;
public CalculateEachRow(CyclicBarrier barrier, int[][] numbers, int rowNumbers, int[] results) {
// TODO 自動生成的構造函數存根
this.barrier = barrier;
this.numbers = numbers;
this.rowNumbers = rowNumbers;
this.results = results;
}
@Override
public void run() {
// TODO 自動生成的方法存根
int[] row = numbers[rowNumbers];
int sum = 0;
for(int data : row)
{
sum+=data;
results[rowNumbers] = sum;
}
try {
System.out.println(Thread.currentThread().getName()+": 計算第"+(rowNumbers+1)+"行結束,結果爲:"+results[rowNumbers]);
barrier.await();//等待,只要超過三個就放行
}catch(Exception e)
{
e.printStackTrace();
}
}
}
class CalculateFinalResult implements Runnable
{
final int[] eachRowResult;
int finalResult;
public CalculateFinalResult(int[] eachRowResult)
{
this.eachRowResult = eachRowResult;
}
public int getFinalResult() {
return finalResult;
}
@Override
public void run() {
// TODO 自動生成的方法存根
int sum = 0;
for(int data: eachRowResult)
{
sum+=data;
}
this.finalResult = sum;
System.out.println("最終結果爲:"+finalResult);
}
}
PhaserExample
package Java併發協作控制;
import java.util.concurrent.Phaser;
public class PhaserExample
{
/*
* 假設舉行考試,總共三道答題,每次下發一個題目,等所有的學生做完後再進行下一道
*/
public static void main(String[] args) {
int studentsCnt = 5;
Phaser phaser = new Phaser(studentsCnt);
for(int i=0;i<studentsCnt;i++)
{
new Thread(new Student(phaser)).start();
}
}
}
class Student implements Runnable
{
private final Phaser phaser;
public Student(Phaser phaser)
{
this.phaser = phaser;
}
@Override
public void run() {
// TODO 自動生成的方法存根
try
{
doTesting(1);
phaser.arriveAndAwaitAdvance();
doTesting(2);
phaser.arriveAndAwaitAdvance();
doTesting(3);
phaser.arriveAndAwaitAdvance();
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
private void doTesting(int i) throws InterruptedException
{
String name = Thread.currentThread().getName();
System.out.println(name+"開始答第"+i+"道");
Thread.sleep((long)(Math.random())*1000);
System.out.println(name+"第"+i+"道答題結束");
}
}
ExchangerExample
package Java併發協作控制;
import java.util.Scanner;
import java.util.concurrent.Exchanger;
import javax.xml.validation.SchemaFactoryConfigurationError;
public class ExchangerExample {
/*
* 本例通過Exchenger實現學生成績查詢,簡單線程間的數據交換
*/
public static void main(String[] args) throws InterruptedException {
Exchanger<String> exchenger = new Exchanger<String>();
BackgroundWorker worker = new BackgroundWorker(exchenger);
new Thread(worker).start();
Scanner in = new Scanner(System.in);
while(true)
{
System.out.println("please input student name");
String input = in.next();
// String input = in.nextLine().trim();
exchenger.exchange(input);
String value = exchenger.exchange(null);
if("exit".equals(value))
break;
System.out.println("查詢結果爲 :" + value);
}
}
}
class BackgroundWorker implements Runnable
{
private Exchanger<String> exchanger;
public BackgroundWorker(Exchanger<String> exchanger) {
// TODO 自動生成的構造函數存根
this.exchanger = exchanger;
}
@Override
public void run() {
// TODO 自動生成的方法存根
while(true)
{
try
{
String item = exchanger.exchange(null);
switch(item)
{
case "zhangsan":
exchanger.exchange("90");
break;
case "lisi":
exchanger.exchange("80");
break;
case "wangwu":
exchanger.exchange("70");
break;
case "exit":
exchanger.exchange("exit");
break;
default:
exchanger.exchange("查無此人");
break;
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}