<span style="font-size:18px;">/**
* 同步輔助類之信號量
* 允許指定共享資源數量,可以允許指定數量的線程同時訪問資源
* 與同步的區別在於,同步時,一次只能一個線程訪問資源
* @author Administrator
*
*/
public class SemaphoreDemo {
public static void main(String[] args) {
final Semaphore semaphore = new Semaphore(2);//指定兩個信號量可同時運行
System.out.println(Thread.currentThread().getState());
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();//獲得一個信號量
System.out.println(Thread.currentThread().getName() + "來了");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "走了");
semaphore.release();//釋放一個信號量
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}</span>
/**
* 同步輔助類之倒計時
* 初始化CountDownLatch時,可以指定一個整數,按該整數可以進行倒計時
* 可以控制指定的線程在倒計時未完成時進行等待
* @author Administrator
*
*/
public class CountDownLatchDemo {
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(1);//初始倒計時從1開始
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "預備");
for (int i = 3; i >= 1; i--) {
System.out.println(i);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "開始");
countDownLatch.countDown();//倒計時減一
}
}).start();
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();//等待倒計時爲0纔會向下執行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "起跑");
}
}).start();
}
}
}
/**
* 同步輔助類之循環等待
* 允許一組線程互相等待,在達到條件後,再同時執行下一步操作
* 並且條件還可以重用
* 下列情景爲四個人全部爬到山頂之後再去吃飯,同時吃完飯再去唱歌以此類推
* @author Administrator
* 與CountDownLatch倒計時類的區別:
* 1.CyclicBarrier是一組線程相互都等待
* 2.CyclicBarrier計數器爲0的時候會自動重置
*/
public class CyclicBarrierDemo {
public static void main(String[] args) {
final CyclicBarrier cyclicBarrier = new CyclicBarrier(4);//從4開始倒計時
for (int i = 0; i < 4; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("準備爬山總人數 : " + cyclicBarrier.getParties());
System.out.println(Thread.currentThread().getName() + "爬山");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "爬到山頂了");
cyclicBarrier.await();//等待,直到計數器變爲0,每等待一次計數器減1,計數器變爲0後會重置爲4
System.out.println("準備吃飯總人數 : " + cyclicBarrier.getParties());
System.out.println(Thread.currentThread().getName() + "吃飯");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "吃完飯了");
cyclicBarrier.await();//等待,直到計數器變爲0,每等待一次計數器減1,計數器變爲0後會重置爲4
System.out.println("準備唱歌總人數 : " + cyclicBarrier.getParties());
System.out.println(Thread.currentThread().getName() + "唱歌");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
System.out.println(Thread.currentThread().getName() + "唱完歌了");
cyclicBarrier.await();//等待,直到計數器變爲0,每等待一次計數器減1,計數器變爲0後會重置爲4
System.out.println("準備回家總人數 : " + cyclicBarrier.getParties());
System.out.println(Thread.currentThread().getName() + "回家");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
/**
* 同步輔助類之交換
* 可以在一對線程之間交換數據
* @author Administrator
*
*/
public class ExchangerDemo {
public static void main(String[] args) {
final Exchanger<String> exchanger = new Exchanger<String>();
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "賣蘋果");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
String apple = "兩斤蘋果";
//線程到此阻塞,直到另一個線程執行exchange方法,與該線程交換數據並獲取另一個線程交換的數據
String money = exchanger.exchange(apple);
System.out.println(Thread.currentThread().getName() + "賣了" + money);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "買蘋果");
TimeUnit.SECONDS.sleep(new Random().nextInt(5));
String money = "十塊錢";
//線程到此阻塞,直到另一個線程執行exchange方法,與該線程交換數據並獲取另一個線程交換的數據
String apple = exchanger.exchange(money);
System.out.println(Thread.currentThread().getName() + "買了" + apple);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}