zoukankan      html  css  js  c++  java
  • 利用线程池,同步线程实现并发

    一、CountDownLatch

    同步工具类,允许一个或多个线程等待,直到其他的线程操作完成后在执行。

    如何工作:

    CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

    使用场景:

    1.实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。

    2.开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。

    3。死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

     

    二、使用countdownlach 和ExecutorService 线程池 编写并发

     countdownlach 同步计数设置为1,countDown 则线程并发

    package com.cyd.util.netty;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * countdownlach 和线程池完成并发 应用场景:1、最大并发。2、执行前等待N线程执行完成。 3、模拟锁死。
     * 
     * @author chenyd 2017年11月29日
     */
    public class Concurrent {
    
        public static void main(String[] args) {
            int threadNum = 5;
            CountDownLatch countd = new CountDownLatch(1);// 同步线程数
            ExecutorService threadPool = Executors.newFixedThreadPool(threadNum);// 线程池
            for (int i = 0; i < threadNum; i++) {
                threadPool.execute(new ChildThread(i,countd));
            }
            try {
                System.out.println("等待添加....");
                Thread.sleep(1000);
                System.out.println("并发....");
                countd.countDown();
            
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                threadPool.shutdown();
                // 关闭线程池,停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
                // threadPool.shutdownNow();
            }
        }
    
    }
    
    class ChildThread implements Runnable {
        private int num;
        private CountDownLatch countd;
        public ChildThread(){};
        public ChildThread(int num,CountDownLatch countd) {
            this.num = num;
            this.countd=countd;
        };
    
        public void run() {
            try {
                countd.await();
                // 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
                // latch.await(long timeout, TimeUnit unit);
                System.out.println("子线程:" + num);
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //当前计算工作结束,计数器减一
                
                try {
                    //Thread.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                 //执行coutDown()之后,继续执行自己的工作,不受主线程的影响
                System.out.println("子线程"+num+"继续执行,不受影响");
            }
        }
    
    }

    参考链接:

    什么时候使用CountDownLatchhttp://www.importnew.com/15731.html

    java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例http://blog.csdn.net/javaloveiphone/article/details/54729821

     

  • 相关阅读:
    Python str转化成数字
    MySQL之CONCAT()的用法
    MySQL之LIMIT用法
    MySQL中LOCATE用法
    设计模式-模版方法
    设计模式-单例模式
    设计模式-桥接模式
    UML图标含义及记忆方法
    redis-分布式锁-消除竞争条件
    redis-分布式锁-刷新信号量
  • 原文地址:https://www.cnblogs.com/litblank/p/7922187.html
Copyright © 2011-2022 走看看