Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JIT会优化这段代码吗?是否需要同步?_Java_Thread Safety_Jit - Fatal编程技术网

Java JIT会优化这段代码吗?是否需要同步?

Java JIT会优化这段代码吗?是否需要同步?,java,thread-safety,jit,Java,Thread Safety,Jit,下面是一个类,它包含拼写错误的术语到拼写正确的术语的映射。quartz作业通过调用updateCache()定期更新映射。方法updatecache处理输入映射中的键和值,并将它们存储在临时映射对象中。处理完成后(for循环之后),它将临时映射分配给本地类变量misspelledToCorrectlySpelled package com.test; 导入java.util.HashMap; 导入java.util.Map 导入org.checkthread.annotations.Threa

下面是一个类,它包含拼写错误的术语到拼写正确的术语的映射。quartz作业通过调用updateCache()定期更新映射。方法updatecache处理输入映射中的键和值,并将它们存储在临时映射对象中。处理完成后(for循环之后),它将临时映射分配给本地类变量misspelledToCorrectlySpelled

package com.test;
导入java.util.HashMap; 导入java.util.Map

导入org.checkthread.annotations.ThreadSafe

@线程安全 公共类拼写更正ListCacheManager{

private Map<String, String> misspelledToCorrectlySpelled = 
    new HashMap<String, String>(0);

/*
 * invoked by a quartz job thread
 */
public void updateCache(Map<String, String> map) {

    Map<String, String> tempMap = new HashMap<String, String>(map.size());

    for (Map.Entry<String, String> entry : map.entrySet()) {
         //process key and values
        String key = entry.getKey().toLowerCase();
        String value = entry.getValue().toLowerCase();

        tempMap.put(key, value);
    }

    // update local variable
    this.misspelledToCorrectlySpelled = tempMap;
}

/*
 * Could be invoked by *multiple* threads
 */
public Map<String, String> getMisspelledToCorrectlySpelled() {
    return misspelledToCorrectlySpelled;
}
您应该使用存储新映射,以避免出现同步和可见性问题。但代码中最大的问题是,您将对非线程安全的可变映射的访问权限授予多个线程。您应该将映射包装为不可修改的映射:

private AtomicReference<Map<String, String>> misspelledToCorrectlySpelled = 
    new AtomicReference<Map<String, String>>(Collections.unmodifiableMap(new HashMap<String, String>(0)));

/*
 * invoked by a quartz job thread
 */
public void updateCache(Map<String, String> map) {

    Map<String, String> tempMap = new HashMap<String, String>(map.size());

    for (Map.Entry<String, String> entry : map.entrySet()) {
         //process key and values
        String key = entry.getKey().toLowerCase();
        String value = entry.getValue().toLowerCase();

        tempMap.put(key, value);
    }

    // update local variable
    this.misspelledToCorrectlySpelled.set(Collections.unmodifiableMap(tempMap));
}

/*
 * Could be invoked by *multiple* threads
 */
public Map<String, String> getMisspelledToCorrectlySpelled() {
    return misspelledToCorrectlySpelled.get();
}
private AtomicReference拼写错误到正确拼写=
新的原子引用(Collections.unmodifiableMap(新的HashMap(0));
/*
*由quartz作业线程调用
*/
公共无效更新缓存(映射){
Map tempMap=newhashmap(Map.size());
对于(Map.Entry:Map.entrySet()){
//过程关键和价值观
String key=entry.getKey().toLowerCase();
字符串值=entry.getValue().toLowerCase();
tempMap.put(键、值);
}
//更新局部变量
this.misspelledToCorrectlySpelled.set(Collections.unmodifiableMap(tempMap));
}
/*
*可由*多个*线程调用
*/
公共地图拼写错误到正确拼写(){
返回拼写错误的tocorrectlyspelled.get();
}

回答您关于JIT优化的问题:不,JIT不会删除临时映射的使用。

需要同步的地方需要同步。除了兼容的实现将兼容JLS和Java内存模型,并且将遵守使用这些规则。(有多种同步方法,并非所有方法都使用
synchronized
关键字。)

这里需要同步,除非“可以”看到一个过时的版本。(这里可能不是这种情况,它可能是一个非常过时的版本,有缓存和所有东西——因此不值得打赌!)。就不可能发生“部分写入”而言,“引用赋值”本身是原子的,但不能保证(立即)是原子的跨所有线程传播(“可见”)


愉快的编码。

谢谢你的评论。我很乐意看到过时的版本-我的假设是最新的版本将在10秒内对所有线程可见。我的假设正确吗?谢谢你的评论。你建议将映射包装成不可修改的映射非常好-我添加了它。如果我的代码是多线程安全的(除了不使用同步时的陈旧/可见性问题)我不想使用AtomicReference或Volatile。您是否看到不使用AtomicReference时存在陈旧问题以外的其他问题?请参阅“清单8.清单7中的优化代码”在本文中,如何确保JIT不会通过删除代码中的tempMap来优化代码?有没有办法检查JIT是否删除了tempMap?
this.misspelledToCorrectlySpelled = new HashMap<String, String>(map.size());

    for (Map.Entry<String, String> entry : map.entrySet()) {
         //process key and values
        String key = entry.getKey().toLowerCase();
        String value = entry.getValue().toLowerCase();

        this.misspelledToCorrectlySpelled.put(key, value);
    }
/*
     * is this assignment atomic operation?
     * 
     * Does this needs to be synchronized? 
     * 
     * By not synchronizing, the new map may not 
     * be visible to other threads *immediately* -- this is 
     * ok since the new map will be visible after a bit of time 
     * 
     */
    this.misspelledToCorrectlySpelled = tempMap;
}
private AtomicReference<Map<String, String>> misspelledToCorrectlySpelled = 
    new AtomicReference<Map<String, String>>(Collections.unmodifiableMap(new HashMap<String, String>(0)));

/*
 * invoked by a quartz job thread
 */
public void updateCache(Map<String, String> map) {

    Map<String, String> tempMap = new HashMap<String, String>(map.size());

    for (Map.Entry<String, String> entry : map.entrySet()) {
         //process key and values
        String key = entry.getKey().toLowerCase();
        String value = entry.getValue().toLowerCase();

        tempMap.put(key, value);
    }

    // update local variable
    this.misspelledToCorrectlySpelled.set(Collections.unmodifiableMap(tempMap));
}

/*
 * Could be invoked by *multiple* threads
 */
public Map<String, String> getMisspelledToCorrectlySpelled() {
    return misspelledToCorrectlySpelled.get();
}