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