在多线程环境下获取每个字符串被获取的次数

在多线程环境下获取每个字符串被获取的次数需要使用线程安全的数据结构来存储和更新计数。在Java中,你可以使用ConcurrentHashMap来实现这个功能。

下面是一个示例代码,展示如何使用多线程统计字符串被获取的次数:

package com.example.demo.service;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class Threadmore {

    private ConcurrentHashMap<String, Integer> countMap = new ConcurrentHashMap<>();

    public void increment(String str) {
        countMap.putIfAbsent(str, 0);
        countMap.computeIfPresent(str, (key, value) -> value + 1);

    }

    public int getCount(String str) {
        return countMap.getOrDefault(str, 0);
    }

    public static void main(String[] args) {
        Threadmore threadmore = new Threadmore();
        ExecutorService service = Executors.newFixedThreadPool(5);
        //创建任务
        Runnable task = () -> {
            String str = "abc";
            threadmore.increment(str);
        };
        for (int i = 0; i < 10; i++) {
            service.submit(task);
        }
        //关闭线程池
        service.shutdown();
        //任务为执行完继续的等待
        while (!service.isTerminated()) {
            //等待。。。。。
        }
        log.info("字符数:{}", threadmore.getCount("abc"));
    }


}

在上面的代码中,ThreadMore类使用ConcurrentHashMap作为计数器的存储结构。increment方法用于增加指定字符串的计数,它使用了putIfAbsent方法来确保在第一次获取字符串时初始化计数为0,然后使用computeIfPresent方法对已存在的字符串计数进行自增操作。

getCount方法用于获取指定字符串的计数,它使用getOrDefault方法来获取字符串的计数,如果该字符串还没有被获取过,则返回0。

注意,ConcurrentHashMap提供了线程安全的操作,可以在多个线程之间安全地进行并发访问和更新。这样,多个线程可以同时调用increment方法来增加计数,而不会产生竞争条件或数据不一致的问题。

ConcurrentHashMap是Java标准库提供的线程安全的哈希表实现。在多线程环境下,多个线程可以同时对ConcurrentHashMap进行读取和写入操作,而不会导致数据不一致或产生竞争条件。

下面是一些使用ConcurrentHashMap的原因:

  1. 线程安全性:ConcurrentHashMap提供了内部的锁机制,保证了在并发情况下的线程安全性。多个线程可以同时对ConcurrentHashMap进行读取和写入操作,而不会导致数据损坏或不一致的情况。

  2. 高性能:ConcurrentHashMap在内部实现上采用了分段锁的方式,将整个哈希表分成多个段,每个段上都有一把锁。这样,在多线程环境下,不同的线程可以同时访问不同的段,减小了锁的竞争,提高了并发性能。

  3. 可伸缩性:ConcurrentHashMap的设计允许多个线程同时对不同的段进行操作,从而提供了更好的可伸缩性。在高并发情况下,ConcurrentHashMap可以有效地支持大量的读取和写入操作,而不会成为性能瓶颈。

  4. 功能完善:ConcurrentHashMap提供了丰富的操作方法,如putIfAbsentcomputeIfPresent等,使得在多线程环境下进行复杂的操作变得更加方便和安全。

ConcurrentHashMap的底层原理是基于分段锁(Segment)和哈希表(Hash table)实现的。

  1. 分段锁(Segment):ConcurrentHashMap将整个哈希表分成多个段(Segment),每个段都维护了一个子哈希表(Hash table)。每个段都拥有自己的锁,多个线程可以同时访问不同的段,减小了锁的竞争范围,提高了并发性能。

  2. 哈希表(Hash table):每个段内部使用哈希表来存储键值对。哈希表的底层数据结构是一个数组,每个数组元素称为一个桶(Bucket)。每个桶可以存储一个或多个键值对,通过哈希算法将键映射到对应的桶中。

  3. 线程安全操作:ConcurrentHashMap使用分段锁来实现线程安全的操作。当多个线程对不同的段进行操作时,它们可以同时进行,不会相互阻塞。当多个线程对同一个段进行操作时,只有该段上的锁被获取,其他段仍然可以被访问。这样,在多线程环境下,ConcurrentHashMap可以提供高效的并发性能。

  4. 扩容:当ConcurrentHashMap的负载因子(load factor)达到阈值时,会触发扩容操作。扩容会创建一个更大的哈希表,并将原有的键值对重新分配到新的桶中。在扩容过程中,仍然可以对ConcurrentHashMap进行读取和写入操作,不会阻塞其他线程。

总结起来,ConcurrentHashMap通过分段锁和哈希表的组合实现了高效的线程安全操作。每个段可以独立进行操作,多个线程可以同时对不同的段进行读取和写入操作,提高了并发性能。同时,它还提供了高度可伸缩性和功能完善的操作方法,使其成为处理并发访问的理想选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值