多线程同步场景与解决方案

1.semaphore 信号量

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
	class SemaphoreRunnable implements Runnable{
		
		private Semaphore semaphore;//信号量 控制同一时间并发数为2
		private int user;//记录第几个用户
		
		public SemaphoreRunnable(Semaphore semaphore,int user) {
			this.semaphore=semaphore;
			this.user=user;
		}

		@Override
		public void run() {
			//获取信号量许可
			try {
				semaphore.acquire();
				System.out.println("用户:"+user+"开始买票。。。。。。。。。。。");
				Thread.sleep((long) (Math.random()*10000));
				System.out.println("用户:"+user+"买票完成。。。。。。。。。。。");
				Thread.sleep((long) (Math.random()*10000));
				System.out.println("用户:"+user+"买票离开。。。。。。。。。。。");
				semaphore.release();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}
	
	private void execute() {
		//定义窗口个数
		final Semaphore semaphore = new Semaphore(2);
		ExecutorService executorService = Executors.newCachedThreadPool();
		for(int i=0;i<20;i++) {
			executorService.submit(new SemaphoreRunnable(semaphore, i+1));
		}
		executorService.shutdown();
	}

	public static void main(String args []) {
		SemaphoreDemo semaphoreDemo = new SemaphoreDemo();
		semaphoreDemo.execute();
	}

}

2.CyclicBarrier

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SyclicBarrierDemo {

	public static void main(String[] args) {
		final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
			
			@Override
			public void run() {
				System.out.println("人已到齐,开始拍照。。。");
			}
		});
		
		//适用场景:多线程合并,最后合并结果
		
		ExecutorService executorService = Executors.newCachedThreadPool();
		
		for( int i=0;i<3;i++) {
			final int user = i+1; 
			Runnable r =new Runnable() {
				@Override
				public void run() {
					//模拟每个人不同时间来
					try {
						Thread.sleep((long) (Math.random()*10000));
						System.out.println("用户:"+user+"到达。。。。。当前有几人等待"+cyclicBarrier.getNumberWaiting());
						
						cyclicBarrier.await();
						
						Thread.sleep((long) (Math.random()*10000));
						if (user==1) {
							System.out.println("拍完照了,开始吃饭");
						}
						
						Thread.sleep((long) (Math.random()*10000));
						System.out.println("用户:"+user+"吃完了。。。。。准备离开");
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					
				}
			};
			
			executorService.submit(r);
		}
		
		
		executorService.shutdown();
	}

}

3.Exchanger 交换

import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExchangeDemo {

	public static void main(String[] args) {
		
		//exchanger 适用场景  用于两个线程交换数据
		//校对工作
		final Exchanger<String> exchanger = new Exchanger<String>();
		
		
		ExecutorService executorService = Executors.newCachedThreadPool();
		
		//1.
		executorService.submit(new Runnable() {
			
			@Override
			public void run() {
				try {
					Thread.sleep((long) (Math.random()*10000));
					String returnStr= exchanger.exchange("小乔");
					System.out.println("张三用小乔交换回来"+returnStr);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
		
		
		//2.
		executorService.submit(new Runnable() {
			
			@Override
			public void run() {
				try {
					Thread.sleep((long) (Math.random()*10000));
					String returnStr= exchanger.exchange("1000w");
					System.out.println("大乔用1000w交换回来"+returnStr);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});	
		
		executorService.shutdown();
		
		
	}

}

4.倒计时计数器

import java.util.concurrent.CountDownLatch;


public class CountDownLatchDemo {

	public static void main(String[] args) {
		final CountDownLatch latch = new CountDownLatch(2);
		
		//任务1
		new Thread() {
			public void run() {
				System.out.println("任务1开始执行");
				try {
					Thread.sleep((long) (Math.random()*10000));
					System.out.println("任务1执行完毕");
					latch.countDown();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}.start();
		
		//任务2
		new Thread() {
			public void run() {
				System.out.println("任务2开始执行");
				try {
					Thread.sleep((long) (Math.random()*10000));
					System.out.println("任务2执行完毕");
					latch.countDown();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}.start();		
		
		System.out.println("等待其他两个线程执行执行完毕,主线程开始执行"+Thread.currentThread().getName());
		
		try {
			latch.await();
			System.out.println("其他两个线程执行执行完毕....,主线程开始执行"+Thread.currentThread().getName());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

猜你喜欢

转载自blog.csdn.net/qq_26769049/article/details/89529425