前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >String的intern方法使用场景

String的intern方法使用场景

作者头像
查拉图斯特拉说
发布2023-12-18 12:35:01
2940
发布2023-12-18 12:35:01
举报
文章被收录于专栏:后端架构

使用场景

intern() 方法是 Java 中的一个方法,它用于将字符串对象添加到字符串常量池中,并返回该字符串在常量池中的引用。

当调用 intern() 方法时,如果字符串常量池中已经存在该字符串,则直接返回常量池中的引用;如果常量池中不存在该字符串,则将该字符串添加到常量池中,并返回新添加的字符串引用。

使用 intern() 方法可以节省内存空间,因为它可以使多个字符串对象共享同一个字符串常量池中的实例。这在处理大量字符串对象时特别有用。

以下是一个示例:

代码语言:javascript
复制
String str1 = new String("Hello");
String str2 = str1.intern();

System.out.println(str1 == str2);  // 输出:false
System.out.println(str1.equals(str2));  // 输出:true

在上面的示例中,str1 是通过 new 关键字创建的新的字符串对象,而 str2 是通过 intern() 方法从常量池中获取的引用。尽管它们的内容相同,但它们是不同的对象。通过比较引用地址可以看出,str1 == str2 的结果为 false,而通过比较内容可以看出,str1.equals(str2) 的结果为 true

`intern()` 方法本身并不能防止并发,但是它可以减少内存使用,从而减少内存溢出的可能性,进而提高程序的稳定性。

这个方法是能防止并发的吗

在多线程环境下,如果多个线程同时调用 `intern()` 方法添加同一个字符串到常量池中,那么常量池中只会存在一个该字符串的实例。这样可以减少内存使用,但是需要注意的是,由于多个线程同时访问常量池,可能会导致线程安全问题。因此,在多线程环境下使用 `intern()` 方法时,需要采取相应的同步措施来确保线程安全。

另外,需要注意的是,使用 `intern()` 方法也可能会带来一些性能问题。由于在常量池中查找字符串需要进行哈希计算和比较操作,因此在大量使用 `intern()` 方法时可能会影响程序的性能。因此,在使用 `intern()` 方法时需要根据具体情况进行权衡和优化。

代码示例

代码语言:javascript
复制
 @Test
    public void testString() throws InterruptedException {
        String str1 = "hello";
        String str2 = new String("hello");
        String str3 = new String("hello");
        System.out.println(str1.hashCode());
        System.out.println(str2.hashCode());
        System.out.println(str1.intern() == str2);
        System.out.println(str2.intern() == str1);
        System.out.println(str3.intern() == str2.intern());
        Map<String, String> map = new ConcurrentHashMap<>();
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            executorService.execute(()->{
            String key = new String("hello" + finalI % 2);
            String value;
            if (Objects.isNull(value = map.get(key))) {
                value = key.intern();
                map.put(key,  value);
            }
            synchronized (value) {
                System.out.println("获得锁:" + value);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    log.error(e.getMessage(), e);
                }
                System.out.println("释放锁:" + value);
            }
        });
        }

        Thread.currentThread().join();
    }
执行结果
代码语言:javascript
复制
99162322
99162322
false
true
true
获得锁:hello1
获得锁:hello0
释放锁:hello0
释放锁:hello1
获得锁:hello0
获得锁:hello1
释放锁:hello1
释放锁:hello0
获得锁:hello0
释放锁:hello0

分析总结

当你在进行一个对象锁的时候可以使用这种方式,锁定某个特定的对象,我这个示例其实随意创建一个对象都可以,只要保证每次都取的是唯一的就可以了,借此引出intern()的部分使用场景。

记得曾经推特的工程师使用intern()对地址进行内存优化,使得原本相同的地址占用不同的内存问题得到了释放,intern()虽然会有性能影响,但是看你的使用场景。

最后 点赞关注评论一键三连,每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用场景
  • 代码示例
    • 执行结果
    • 分析总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档