java string compareTo返回的结果与equals

时间:2015-08-26 09:41:02

标签: java string

我们在申请中看到了非常奇怪的行为。 我们有这个简单的代码:

public boolean isPrimitiveType()
{
    for (int i=0;i<m_primitiveTypes.length; i++)
    {
        if (m_type.compareTo(m_primitiveTypes[i]) == 0)
        {
            if (log.isDebugEnabled())
            {
                log.fatal("isPrimitiveType() - type="+m_type+", checking with " + m_primitiveTypes[i] + " iteration " + i + " result " + m_type.compareTo(m_primitiveTypes[i]) + " array " 
            + Arrays.toString(m_primitiveTypes) + " with equals " + m_type.equals(m_primitiveTypes[i]));
            }
            return true;
        }
    }
    return false;
}

数组m_primitiveTypes非常简单:[java.lang.String,boolean,int,long,float,short]

类型:m_primitiveTypes是String [],m_type是String。

我们看到的是,经过一段时间(对该方法的多次调用),我们看到错误的结果 - 我们将此方法称为“m_type”等于“java.util.Vector”,但它返回true,尽管它应该返回假。 上面的致命日志显示了这一行:

2015-08-26 02:18:32,665 [WSM_REQUEST_SERVICE(1)(pid:14529)] FATAL com.intel.swiss.sws.mechanism.pxml.PXMLTag - isPrimitiveType() - type=java.util.Vector, checking with java.lang.String iteration 0 result 0 array [java.lang.String, boolean, int, long, float, short] with equals false

这很奇怪 - 似乎“java.util.Vector”.compareTo(“java.util.String”)返回0而“java.util.Vector”.equals(“java.util.String”)返回假的。

也许compareTo不是线程安全的?正如我所说的那样,只有在经过一段时间后才会发生这种情况。即使在它发生之后,在某些情况下它也能按预期工作。

对这个谜团有什么猜测?

由于

更新:

我创建了这个隔离代码的类,但仍然会重现问题:

import java.util.Random;

public class PXMLTag 
{
public String m_type;
public static Random m_random = new Random();
private static String[] m_primitiveTypes = {"java.lang.String",
                                            "boolean",
                                            "int",
                                            "long",
                                            "float",
                                            "short"};

private static String[] m_allTypes = {"java.lang.String",
        "boolean",
        "int",
        "long",
        "float",
        "java.util.Vector",
        "java.util.Map",
        "short"};

public PXMLTag() 
{
    super();
}

public boolean isPrimitiveType()
{
    for (int i=0;i<m_primitiveTypes.length; i++)
    {
        String type = m_type;
        String primitiveType = m_primitiveTypes[i];
        if (type.compareTo(primitiveType) == 0)
        {
            return true;
        }
    }
    return false;
}

public static void main(String[] args)
{
    int threads = 1;
    if (args.length == 1)
    {
        threads = Integer.parseInt(args[0]);
    }
    for (int i=0 ; i<threads ; i++)
    {
        Thread t = createThread();
        t.start();
    }
}

private static Thread createThread()
{
    return new Thread(new Runnable(){

        @Override
        public void run()
        {
            while (true)
            {
                PXMLTag tag = new PXMLTag();
                tag.m_type = getRandomType();
                if (tag.isPrimitiveType() && notReallyPrimitiveType(tag.m_type))
                {
                    System.out.println(tag.m_type + " not really primitive!");
                    System.exit(0);
                }
                try
                {
                    Thread.sleep(m_random.nextInt(100));
                } catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        private boolean notReallyPrimitiveType(String m_type)
        {
            return m_type.contains("Vector") || m_type.contains("Map");
        }

        private String getRandomType()
        {
            return m_allTypes[m_random.nextInt(m_allTypes.length)];
        }});
}
}

当运行5个线程时,程序在22秒后停止(意思是 - 重现问题): 时间/usr/intel/pkgs/java/1.7.0.45-64/bin/java -jar /tmp/tag.jar 5 java.util.Vector不是很原始! 0.036u 0.012s 0:22.38 0.1%0 + 0k 0 + 128io 0pf + 0w

即使有一个线程,我也能够重现这个问题: 时间/usr/intel/pkgs/java/1.7.0.45-64/bin/java -jar /tmp/tag.jar 1 java.util.Vector不是很原始! 0.048u 0.012s 1:46.92 0.0%0 + 0k 0 + 128io 0pf + 0w

我发现的另外一件事 - 在有问题的机器上,有5个线程 - 程序总是在~21-22秒后停止,这是巧合吗?我怀疑某种JIT优化可能吗? 对此有何想法?

对Marco的回应:我已经添加了你想要的版画,这就是我得到的:

这个奇怪的案例

输入'java.util.Map'

currentPrimitiveType'java.lang.String'

他们是平等的?假

他们被比较9

m_type'java.util.Map'

m_primitiveType [i]'java.lang.String'

他们是平等的?假

他们被比较9

java.util.Map不是很原始!

所以比较结果是9但是打印在if子句中,只有在比较结果为0时输入!

更新2:

我发现非常有趣的事情 - 使用-Xint(禁用热点编译器)运行相同的问题不会重现该问题。

0 个答案:

没有答案