【问题标题】:Thread Safe String Split线程安全字符串拆分
【发布时间】:2013-01-02 16:55:04
【问题描述】:

我已经使用 StringTokenizer 和 String 的方法 indexOf() 和 substring() 进行了拆分测试。结果我必须知道,第二个比 StringTokenizer 快。但我的问题是哪个最适合线程安全?

使用 StringTokenizer 分割字符串:

String sample=null;
StringTokenizer tokens = new StringTokenizer("FF#Mukil","#");

if(tokens.hasMoreTokens())
{
    sample= tokens.nextToken();
    System.out.println(sample);
}

使用String的方法拆分字符串:

String sample= "FF#Mukil";
int pos=sample.indexOf('#');
System.out.println(sample.substring(0,pos));

在这些示例中,sample 是全局变量 提前致谢

编辑: 在前面的第一个示例如下所示

StringTokenizer tokens = new StringTokenizer("FF#Mukil","#");

    if(tokens.hasMoreTokens())
    {
        String sample= tokens.nextToken();
        System.out.println(sample);
    }

我已经改成下面这样了

String sample=null;
StringTokenizer tokens = new StringTokenizer("FF#Mukil","#");

    if(tokens.hasMoreTokens())
    {
        sample= tokens.nextToken();
        System.out.println(sample);
    }

已编辑:添加了 java 文件源。

//FileName=MySplitUtil.java
import javax.servlet.http.HttpServletRequest;
import java.util.StringTokenizer;
public class MySplitUtil
{
    public static void setUsername_locale(HttpServletRequest request)
    {
        String value = (String) request.getAttribute("userLocale"); // userLocale's sample value looks like ffmukil$en_US
        splite1(value,request);
        splite2(value,request);
    }
    private static void splite1(String value,HttpServletRequest request)
    {
        StringTokenizer tokens = new StringTokenizer(value,"$");
        String username=null;
        String locale=null;
        if(tokens.hasMoreTokens())
        {
            username = tokens.nextToken();
            locale = tokens.nextToken();
        }
        request.setAttribute("usrName",username);
        request.setAttribute("usr_Locale",locale);
    }
    private static  void splite2(String value,HttpServletRequest request)
    {
        int pos = value.indexOf('$');
        String username = value.substring(0,pos);
        String locale = value.substring(pos+1,value.length());
        request.setAttribute("usrName",username);
        request.setAttribute("usr_Locale",locale);
    }
}

【问题讨论】:

  • 我没有看到您的代码在多线程环境中有任何问题。
  • 你能展示你的变量如何在多线程环境中使用吗?您当前的代码显示不需要同步。
  • @Jayamohan,你是怎么检查的?你能告诉我吗?
  • @JoshDM,我有一个使用 Apache 服务器和 Struts1 框架的网络应用程序。我在一个操作文件中使用该示例。
  • @FF Mukil - 根据您的代码,您似乎只在 METHOD SCOPE 中声明和使用变量。如果上面的所有代码都在方法中,即使这些方法同时被多个线程命中,任何一个线程的操作都不会影响另一个线程引用的数据。如果您的变量被声明为 CLASS 范围,那么我们就会遇到问题,但就目前而言,这里没有多线程问题。

标签: java performance split


【解决方案1】:

由于您只使用局部变量,因此这两个版本都非常安全,无论您对它们做什么......

要遇到线程安全问题,您需要(不正确地)跨线程共享某些内容。在您的示例中无法共享任何内容。

更一般地说,字符串是不可变的,因此是线程安全的。所以第二个版本,假设 sample 变量是共享的,将是线程安全的。

编辑

您的最新编辑确认了两件事:

  • 你的类是无状态的(没有实例变量)
  • 你只使用局部变量

所以这两种方法都是线程安全的,您应该选择更简单和/或更高效的方法。

【讨论】:

  • assylias,对不起。我对局部变量(示例)进行了一些更改。
  • @FFMukil 您的编辑仍不清楚 - 显示您的类的代码,以及相关字段(示例?)和方法。
【解决方案2】:

在java中,Strings是不可变的,不会影响原来的字符串。

这种不变性使Strings 线程安全。多个StringTokenizerstring.substring可以同时访问,没有任何问题。

但是,问题可能来自 StringTokenizer 类,您不应该同时对多个字符串使用该类。但是,正如其他人所指出的,在您的代码中您只使用局部变量,因此您不会遇到线程安全问题。

【讨论】:

  • 首先感谢您的回复。我使用样本作为全局变量。这里只有我把它改成了局部变量。
【解决方案3】:

根据 Javadoc:“StringTokenizer 对象在内部维护要标记化的字符串中的当前位置。一些操作将当前位置推进到处理的字符之后。”

所以它不是线程安全的。你为什么要分享它呢?只需将其设为局部变量即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2012-10-20
    • 2011-08-16
    • 2015-09-05
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多