java并发工具类

等待多线程完成

主线程等待所有线程完成工作

实现

thread.join()方法


    private static void join() throws InterruptedException {
        int length = 100;

        Long t1 = System.nanoTime();
        List<Integer> results = new ArrayList<>();
        for (int index = 0; index < length; index++) {
            final int threadIndex = index;
            Thread thread = new Thread(() -> {
                System.out.println("start thread - " + threadIndex);
                Double random = -1.0;
                try {
                    Thread.sleep(1 * 1000);
                    random = (100 * Math.random());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("stop thread - " + threadIndex + " random = " + random.intValue());
                results.add(random.intValue());

            });
            thread.start();
            thread.join();
        }

        System.out.println("跑完了...");
        Long t2 = System.nanoTime();
        System.out.println(results);
        System.out.println("time = " + (t2 - t1));
    }

原理

join 用于让当前执行线程等待join线程执行结束。
其实现原理是不停检查join线程是否存活,如果join线程存活则让当前线程永远等待。
其中,wait(0)表示永远等待下去

while(isAlive){
     wait(0);
}

直到join线程中止后,线程的this.notifyAll()方法会被调用,调用notifyAll()是在JVM实现的,所以在jdk里看不到

CountDownLatch

 private static void countDownLatch() throws InterruptedException {
        int length = 100;
        CountDownLatch latch = new CountDownLatch(length);

        Long t1 = System.nanoTime();
        List<Integer> results = new ArrayList<>();
        for (int index = 0; index < length; index++) {
            final int threadIndex = index;
            Thread thread = new Thread(() -> {
                System.out.println("start thread - " + threadIndex);
                Double random = -1.0;
                try {
                    Thread.sleep(1 * 1000);
                    random = (100 * Math.random());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("stop thread - " + threadIndex + " random = " + random.intValue());
                results.add(random.intValue());
                latch.countDown();

            });
            thread.start();
        }

        // 注意:CountDownLatch要加上这段才生效,原因见下面文字描述
        latch.await();

        System.out.println("跑完了...");
        Long t2 = System.nanoTime();
        System.out.println(results);
        System.out.println("time = " + (t2 - t1));
    }

原理

CountDownLatch的构造函数接受一个int类型的参数作为计数器,如果你想等待N个节点(N个Thread 如上述示例 ),这里就传入N

CountDownLatch.countDown()

调用CountDownLatch.countDown() ,N就会减1

CountDownLatch.wait()

CountDownLatch.wait()会阻塞当前线程,直到N变成零

当某个线程处理的特别慢时,如果不需要主线程一直等待下去,可以使用另外一个重载的wait(long time,TimeUnit unit),这个方法等待指定时间后就不再阻塞线程了

join也有类似的方法

结论

join()与CountDownLatch都能实现 主线程等待所有线程完成工作 的功能,但明显 CountDownLatch 效率更高

控制并发线程数

Semaphore

public class StudySemaphore {

    public static void main(String[] args) {
        int THREAD_COUNT = 30;
        ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);

        Semaphore semaphore = new Semaphore(5);

        for (int index = 0; index < THREAD_COUNT; index++) {
            threadPool.execute(() -> {
                try {
                    semaphore.acquire();

                    Thread.sleep(1 * 1000);
                    System.out.println(String.format("%s do with something end - 当前等待的线程数:%s", Thread.currentThread().getName(), semaphore.getQueueLength()));
                    semaphore.release();

                } catch (InterruptedException e) {
                    //
                }

            });
        }

        threadPool.shutdown();
    }
}

原理

Semaphore 的构造方法接受一个int类型的参数,表示可用的许可证数量
new Semaphore(5) 表示允许5个线程获取许可证,也就是最大并发数5

Semaphore.acquire()

Semaphore.acquire() 方法获取一个许可证

Semaphore.release()

使用完后调用 Semaphore.release() 方法归还许可证

Semaphore.tryAcquire()

也可以使用 tryAcquire() 尝试获取许可证

学习《java并发编程的艺术》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容