多线程同步辅助类

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


发布了84 篇原创文章 · 获赞 3 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章