【Java】多线程 并发工具类 & 线程池

并发工具类

CountDownLatch

CountDownLatch允许一个或多个线程等待其他线程完成操作,相当于计数器

代码实例

staticCountDownLatch c = new CountDownLatch(2);

public static void main(String[] args)throws InterruptedException{
    new Thread(
        new Runnable){
            @Override
            public void run(){
                System.out.println(1);
                c.countDown();
                System.out.println(2);
                c.countDown();
            }
        }
    ).start();
    c.await();
    System.out.println("3");
}

CyclicBarrier

让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障取消,被拦截的线程继续运行,相当于限定人数放行的屏障门

相对于CountDownLatch,CyclicBarrier的计数器可以使用reset()重置,而CountDownLatch的计数器只能使用一次;
另外,getNumberWaiting() 可以获得阻塞的线程数量,isBroken()可以了解是否被中断;

代码实例

staticCyclicBarrier c = new CyclicBarrier(2);

public static void main(String[] args){
    new Thread(
        new Runnable(){
            @Override
            public void run(){
                try{
                    c.await();
                }catch(Exception e){ }
                System.out.println(1);
            }
        }
    ).start();

    try{
        c.await();
    }catch(Exception e){ }
    System.out.println(2);
}

Semaphore

Semophore用来控制同时访问特定资源,通过协调各个线程,保证合理使用公共资源,相当于限流器

代码实例

private static final int THREAD_COUNT = 30;
private static ExecutorServicethreadPool = Executors.newFixedThreadPool(THREAD_COUNT);
pirvate static Semaphore s = new Semaphore(10);

public static void main(String[] args){
    for(inti = 0; i<THREAD_COUNT; i++){
        threadPool.execute(
            @Override
            public void run(){
                try{
                    s.acquire();
                    System.out.println("save data");
                    s.release();
                }catch(InterruptedException e){ }
            }
        );
    }
    threadPool.shutdown();
}

Exchanger

Exchanger用于线程间协作,进行线程间数据交换;
提供一个同步点,在同步点两个线程可以交换彼此数据;

代码实例

private static final Exchanger<String> exchanger = new Exchanger<String>();
private static ExecutorServicethreadPool = Executors.newFieldThreadPool(2);

public static void main(String[] args){
    threadPool.execute(
        new Runnable(){
            @Override
            public void run(){
                try{
                    String A = "银行流水A";
                    exchanger.exchange(A);
                }catch(InterruptedException e){ }
            }
        }
    );

    threadPool.execute(
        new Runnable(){
            @Override
            public void run(){
                try{
                    String B = "银行流水B";
                    String A = exchanger.exchange(B);
                    System.out.println("A和B是否一致:" + A.equals(B));
                }catch(InterruptedException e){ }
            }
        }
    );

    threadPool.shutdown();
}

线程池

好处

  1. 降低资源消耗,不用重复创建销毁线程;
  2. 提高相应速度,立即执行,无须创建;
  3. 提高线程的可管理性;

操作

创建线程池:

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds, runnableTaskQueue, handler);

execute提交任务:

threadPool.execute(
    new Runnable(){
        @Override
        public void run(){ 
            //TODO
        }
    }
);

submit提交任务:

Future<Object> future = executor.submit(harReturnValuetask);
try{
    Object s = future.get();
}catch(Exception e){
}finally{
    executor.shutdown();
}

小结

并发工具类提供了并发流程控制的手段,而线程池则提高了线程的管理,优化了性能;
总之,他们都在不同业务场景为我们提供线程的控制和管理

猜你喜欢

转载自blog.csdn.net/Francis123580/article/details/80623277