Java中的并发编程工具类实战

指尖流年 2020-06-09 ⋅ 14 阅读

1. 前言

随着计算机硬件的发展,多核处理器变得越来越常见。为了利用多核处理器的能力,我们需要编写能够并发执行的代码。然而,并发编程往往比较困难,因为不同线程之间的访问资源冲突可能导致不一致的结果。为了解决这个问题,Java提供了一些并发编程工具类,本文将介绍一些常用的并发编程工具类,并通过示例代码演示如何使用它们。

2. CountDownLatch

CountDownLatch是一个同步工具类,它允许一个或多个线程等待其他线程完成操作后再继续执行。CountDownLatch内部维护了一个计数器,初始化时指定计数器的值,并通过调用countDown()方法来减少计数器的值。当计数器的值为0时,等待的线程将被唤醒。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 5;
        CountDownLatch latch = new CountDownLatch(threadCount);
        
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                // 线程执行一些操作...
                latch.countDown();
            }).start();
        }
        
        latch.await();
        System.out.println("所有线程执行完成");
    }
}

上面的示例代码中,创建了5个线程,并通过CountDownLatch来等待这5个线程执行完成。在每个线程执行完操作后,通过countDown()方法减少计数器的值。主线程通过调用await()方法来等待计数器的值变为0,从而实现等待所有线程执行完成。

3. CyclicBarrier

CyclicBarrier也是一个同步工具类,它允许多个线程在一个临界点上互相等待。与CountDownLatch不同的是,CyclicBarrier可以被重置并可以循环使用。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        int threadCount = 5;
        CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {
            System.out.println("所有线程都到达了临界点");
        });
        
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                // 线程执行一些操作...
                
                try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

上面的示例代码中,创建了5个线程,并通过CyclicBarrier来等待这5个线程到达临界点。主线程通过调用await()方法来等待其它线程到达临界点,当所有线程都到达临界点时,将会执行CyclicBarrier的构造函数中传入的Runnable对象。

4. Semaphore

Semaphore是一个计数信号量,它用来控制同时访问某个资源的线程数量。通常用于限制线程的数量或保护共享资源。

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    public static void main(String[] args) {
        int threadCount = 5;
        Semaphore semaphore = new Semaphore(3);
        
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    // 访问共享资源...
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
            }).start();
        }
    }
}

上面的示例代码中,创建了5个线程,并通过Semaphore限制同时访问共享资源的线程数量为3。在每个线程访问共享资源之前,先通过acquire()方法获取许可,如果没有许可将会阻塞线程。访问完成后,通过release()方法释放许可。

5. BlockingQueue

BlockingQueue是一个阻塞队列,它支持在队列为空时的线程等待,或者在队列满时的线程等待。

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
        
        new Thread(() -> {
            while (true) {
                try {
                    int value = queue.take();
                    // 处理从队列中取出的元素...
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        
        new Thread(() -> {
            while (true) {
                try {
                    queue.put(1);
                    // 向队列中添加元素...
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

上面的示例代码中,创建了一个长度为10的阻塞队列,并创建了两个线程,一个线程负责从队列中取出元素,另一个线程负责向队列中添加元素。当队列为空时,取出元素的线程将会阻塞等待;当队列满时,添加元素的线程将会阻塞等待。

6. Conclusion

本文介绍了Java中一些常用的并发编程工具类,并通过示例代码演示了它们的使用方法。这些工具类可以帮助我们更好地利用多核处理器,提高程序的执行效率。希望通过本文的介绍,读者对Java并发编程工具类有了更深入的了解。


全部评论: 0

    我有话说: