Java併發協作控制

目錄

LockExample

SemaphoreExample

CountDownLatchExample

CyclicBarrierExample

PhaserExample

ExchangerExample


 

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();
				}
			}
	
	}
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章