zoukankan      html  css  js  c++  java
  • 常用Concurrent.util包工具类——高并发

    一 Concurrent.util常用类:

    1. CyclicBarrier: 假设有场景:每个线程代表一个跑步运动员,当运动员都准备好后,才一起出发只要有一个人没有准备好,大家都等待。

    import java.util.Random;
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class UseCyclicBarrier {
    
    	static class Runner implements Runnable {
    		private CyclicBarrier barrier;
    		private String name;
    		
    		public Runner(CyclicBarrier barrier, String name) {
    			super();
    			this.barrier = barrier;
    			this.name = name;
    		}
    
    		@Override
    		public void run() {
    			try {
    				Thread.sleep(1000 * (new Random()).nextInt(5));
    				System.out.println(name + "准备OK");
    				barrier.await();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			} catch (BrokenBarrierException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			System.out.println(name + "Go!");
    		}
    	}
    	public static void main(String[] args) {
    		CyclicBarrier barrier = new CyclicBarrier(3);
    		ExecutorService pool = Executors.newFixedThreadPool(3);
    		pool.execute(new Runner(barrier, "b1"));
    		pool.execute(new Runner(barrier, "b2"));
    		pool.execute(new Runner(barrier, "b3"));
    		pool.shutdown();
    	}
    
    }
    
    

    运行结果:
    b3准备OK
    b2准备OK
    b1准备OK
    b2Go!
    b1Go!
    b3Go!

    2. CountDownLacth:经常用于监听某些初始化操作,等初始化执行完毕后,通知主线程继续工作

    import java.util.concurrent.CountDownLatch;
    
    public class UseCountDownLatch {
    
    	public static void main(String[] args) {
    		final CountDownLatch cDownLatch = new CountDownLatch(2);
    		Thread t1 = new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				System.out.println("进入线程t1,等待其他线程处理完成...");
    				try {
    					cDownLatch.await();
    					//当CountDownLatch构造函数的参数减为0时,该线程才继续执行
    					System.out.println("t1线程继续执行...");
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}, "t1");
    		
    		Thread t2 = new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				System.out.println("t2线程执行初始化操作...");
    				try {
    					Thread.sleep(3000);
    					System.out.println("t2线程初始化操作完成,通知t1线程继续...");
    					cDownLatch.countDown();
    					//CountDownLatch构造函数的参数-1
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}, "t2");
    		Thread t3 = new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				System.out.println("t3线程执行初始化操作...");
    				try {
    					Thread.sleep(4000);
    					System.out.println("t3线程初始化操作完成,通知t1线程继续...");
    					cDownLatch.countDown();
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}, "t3");
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    
    }
    
    

    运行结果:
    进入线程t1,等待其他线程处理完成...
    t2线程执行初始化操作...
    t3线程执行初始化操作...
    t2线程初始化操作完成,通知t1线程继续...
    t3线程初始化操作完成,通知t1线程继续...
    t1线程继续执行...

    区别:CyclicBarrier所有线程都阻塞;CountDownLatch只有一个(主)线程阻塞等待

    3. Future和Callable:该模式非常适合在处理很耗时的业务逻辑时进行使用,可以有效的减少系统的响应时间,提高系统的吞吐量

    public class UseFuture implements Callable<String>{
    	private String para;
    
    	public UseFuture(String para) {
    		super();
    		this.para = para;
    	}
    
    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		String querystr = "query";
    		//构造FutureTask,并且传入需要真正进行业务处理的类,该类实现了Callable接口
    		FutureTask<String> future = new FutureTask<>(new UseFuture(querystr));
    		FutureTask<String> future2 = new FutureTask<>(new UseFuture(querystr));
    		//创建一个固定线程数量的线程池
    		ExecutorService pool = Executors.newFixedThreadPool(2);
    		//这里提交任务的future,则开启线程执行RealData的call()
    		Future f = pool.submit(future);
    		Future f2 = pool.submit(future2);
    		//submit和execute的区别:submit可以实现calabale接口的对象;submit有返回值
    		System.out.println("请求完毕");
    //		while(true) {
    			//f.get()判断RealData是否执行完毕
    //			if(f.get() == null){
    //				System.out.println("---------------");
    				//future.get()获取ReadData
    //				System.out.println("数据:" + future.get());
    //				break;
    //			}
    //		}
    		try {
    			//处理其他实际业务逻辑
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		System.out.println("数据:" + future.get());
    		System.out.println("数据:" + future2.get());
    		//并行处理,一共等待3秒
    		pool.shutdown();
    	}
    
    	@Override
    	public String call() throws Exception {
    		//模拟执行耗时
    		Thread.sleep(3000);
    		String result = this.para + "处理完成";
    		return result;
    	}
    
    }
    

    运行结果:
    请求完毕
    数据:query处理完成
    数据:query处理完成

    4. Semaphore信号量

    Semaphore信号量非常适合高并发访问,新系统在上线之前,要对系统的访问量进行评估,当然这个值肯定不是随便拍拍脑袋就能想出来的,是经过以往的经验、数据、历年的访问量、以及推广粒力度进行的一个合理的评估,当然评估标准不能太大也不能太小,太大的话投入的资源达不到实际效果,浪费资源,太小的话,某个时间点一个峰值的访问量上来直接可以压垮系统。
    相关概念:

    1. PV(Page View):网站的总访问量,页面浏览量或点击量,用户每刷新一次就会被记录一次
    2. UV(Unlque Visitor):访问网站的一台电脑客户端为一个访客,一般来讲,时间上以00:00-24:00之内相同IP的客户端只记录一次
    3. QPS(Query Per Second):每秒查询数,qps很大程度上代表了系统业务的繁忙程度,每次请求的背后,可能对应着多次磁盘IO,多次网络请求,多个cpu时间片等。我们通过qps可以非常直观的了解当前系统业务情况,一旦当前qps超过所设定的预警阀值,可以考虑增加机器对集群扩容,以免压力过大导致宕机,可以根据前期的压力测试得到估值,再结合后期综合运维情况,结算出阀值。
    4. RT(Response Time):请求的响应时间,这个指标非常关键,直接说明前期用户的体验,因此任何系统设计师都想降低rt时间。
    5. 当然还涉及到cpu、内存、网络、磁盘等情况,更细节的问题很多,如select、update、delete/ps等数据库层面的统计。

    应对高并发环境:

    1. 网络层面
    2. 服务层面:多台ng服务器做分流负载均衡
    3. Java业务上进行模块化划分
  • 相关阅读:
    hadoop再次集群搭建(3)-如何选择相应的hadoop版本
    48. Rotate Image
    352. Data Stream as Disjoint Interval
    163. Missing Ranges
    228. Summary Ranges
    147. Insertion Sort List
    324. Wiggle Sort II
    215. Kth Largest Element in an Array
    快速排序
    280. Wiggle Sort
  • 原文地址:https://www.cnblogs.com/zys-blog/p/9430287.html
Copyright © 2011-2022 走看看