前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java线程池和并发集合(二)

java线程池和并发集合(二)

原创
作者头像
堕落飞鸟
发布2023-04-04 08:59:25
2190
发布2023-04-04 08:59:25
举报
文章被收录于专栏:飞鸟的专栏

二、并发集合

在多线程环境下,Java提供了一系列线程安全的集合类,称为并发集合。并发集合可以保证在多线程环境下,对集合的操作是线程安全的,不会出现线程安全问题。Java中常见的并发集合包括:ConcurrentHashMap、ConcurrentLinkedQueue、CopyOnWriteArrayList等。

ConcurrentHashMap

ConcurrentHashMap是一种线程安全的HashMap实现,支持高并发的读写操作。ConcurrentHashMap内部采用分段锁的机制,每个段(Segment)维护着一个HashEntry数组,多个线程可以同时访问不同的段,从而提高了并发性能。示例代码如下:

代码语言:javascript
复制
arduinoCopy codeConcurrentMap<String, String> map = new ConcurrentHashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
String value = map.get("key1");

ConcurrentLinkedQueue

ConcurrentLinkedQueue是一种线程安全的队列实现,基于链表实现。ConcurrentLinkedQueue内部采用CAS(Compare And Swap)算法实现并发安全,不需要使用锁。示例代码如下:

代码语言:javascript
复制
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
queue.offer("element1");
queue.offer("element2");
String element = queue.poll();

CopyOnWriteArrayList

CopyOnWriteArrayList是一种线程安全的List实现,基于数组实现。CopyOnWriteArrayList的写操作会创建一个新的数组,并将原数组的数据复制到新数组中,然后将新数组赋值给内部数组,从而保证写操作不会影响到其他线程的读操作。示例代码如下:

代码语言:javascript
复制
List<String> list = new CopyOnWriteArrayList<>();
list.add("element1");
list.add("element2");
String element = list.get(0);

三、示例

下面通过一个示例来演示如何使用线程池和并发集合。

假设有一个任务需要读取多个文件中的数据,并统计每个单词出现的次数,最终将结果输出到文件中。假设有100个文件需要处理,每个文件的大小为100MB。我们可以使用线程池和并发集合来实现这个任务。

首先,我们可以使用CachedThreadPool来创建一个可缓存的线程池,因为任务的大小是不确定的,线程池的大小需要根据实际情况动态调整。

代码语言:javascript
复制
ExecutorService executor = Executors.newCachedThreadPool();

然后,我们可以使用ConcurrentHashMap来存储每个单词出现的次数,因为ConcurrentHashMap是线程安全的HashMap实现。

代码语言:javascript
复制
ConcurrentMap<String, Integer> wordCount = new ConcurrentHashMap<>();

接着,我们可以创建一个任务类,用来读取文件中的数据并更新单词出现次数。任务类需要实现Runnable接口,示例代码如下:

代码语言:javascript
复制
class WordCountTask implements Runnable {
    private File file;
    private ConcurrentMap<String, Integer> wordCount;

    public WordCountTask(File file, ConcurrentMap<String, Integer> wordCount) {
        this.file = file;
        this.wordCount = wordCount;
    }

    @Override
    public void run() {
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] words = line.split(" ");
                for (String word : words) {
                    wordCount.compute(word, (k, v) -> v == null ? 1 : v + 1);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

最后,我们可以提交任务到线程池中,并等待所有任务执行完成。执行完所有任务后,我们可以将单词出现次数按照字典序排序,并输出到文件中。

代码语言:javascript
复制
File[] files = new File("path/to/files").listFiles();
for (File file : files) {
    executor.submit(new WordCountTask(file, wordCount));
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

List<Map.Entry<String, Integer>> list = new ArrayList<>(wordCount.entrySet());
list.sort(Map.Entry.comparingByKey());

try (PrintWriter writer = new PrintWriter(new FileWriter("output.txt"))) {
    for (Map.Entry<String, Integer> entry : list) {
        writer.println(entry.getKey() + " " + entry.getValue());
    }
} catch (IOException e) {
    e.printStackTrace();
}

以上就是使用线程池和并发集合实现任务的示例代码。通过使用线程池和并发集合,我们可以提高任务的执行效率和并发性能,同时避免线程安全问题。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、并发集合
    • ConcurrentHashMap
      • ConcurrentLinkedQueue
        • CopyOnWriteArrayList
        • 三、示例
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档