简体   繁体   English

同步块中的Java内存模型

[英]java memory model in synchronized block

I have confuse about memory model in java, the example as following code : 我对Java中的内存模型感到困惑,示例如下所示:

 /**
  * one thread write request and wait for response
  */
public AbstractPacket writeMessageAndWaitForResp(AbstractPacket packet, int waitTimeoutInSecond) {
        if (!(packet instanceof SendToRouter)) {
            throw new IllegalArgumentException("this msg can not be sent to router!");
        }

        int command = packet.getResponseCommand();
        AbstractPacket[] slot = new AbstractPacket[]{NullPacket.NULL};
        synchronized (("" + this.getFactoryId() + this.getRouterNo() + command).intern()) {// prevent same command request re-entry
            command2RespMap.put(command, slot);
            synchronized (slot) { // prevent notify before wait
                ChannelFuture future = writeMessage(packet);
                if (future == null) {
                    command2RespMap.remove(command);
                    return null;
                }

                try {
                    slot.wait(waitTimeoutInSecond * 1000);
                } catch (InterruptedException e) {
                    logger.error(e.getMessage(), e);
                }
            }
            command2RespMap.remove(command);
        }
        AbstractPacket result = slot[0]; // get out the result outof slot array
        if (result == NullPacket.NULL) {
            logger.error("receive sync message timeout!");
            return null;
        }
        return result;
}

 /**
  * another thread write response and notify the waiter
  */
 public void routerResponse(AbstractPacket packet) {
        int command = packet.getHeadCommand();
        AtomicReference<AbstractPacket> slot = command2RespMap.get(command);
        if (slot == null || slot.get() != NullPacket.NULL) {
            logger.error("command : {} request not exist !", command);
            return;
        }
        synchronized (slot) {
            slot[0] = packet;
            slot.notify();
        }
}

My question is , in the first function, I got the result from slot in index 0 out of the synchronized block on slot variable. 我的问题是,在第一个函数中,我从插槽变量上的同步块中的索引0中的插槽中得到了结果。

does this mean the slot[0] may not contains the value set by the second function in another thread ? 这是否意味着slot [0]可能不包含另一个线程中第二个函数设置的值?

very thanks ! 很感谢 !

synchronized key words, as a memory barrier, guarantees 2 things synchronized关键词作为记忆障碍,可以保证两件事

  1. The compiler might swap the ordering of some statements in your program. 编译器可能会交换程序中某些语句的顺序。 However, upon seeing a synchronized block, any statement in the block won't be re-ordered or mixed with the statements outside of the synchronized block. 但是,看到同步块后,该块中的任何语句都不会重新排序,也不会与同步块外部的语句混合。

  2. Inside the block, any variables would have it's value fetched from main memory and the thread local copy and/or the L2 cache/register cached value would be discarded. 在该块内部,任何变量都会从主内存中获取其值,并且线程本地副本和/或L2缓存/寄存器缓存的值将被丢弃。 Upon the end of the block, the variables modified in the block would be written back to the main memory so that all other threads would read up the same value. 在该块结束时,在该块中修改的变量将被写回到主存储器,以便所有其他线程将读取相同的值。

So, since you refer to slot[0] outside of the synchronized block, there is no guarantee that this reference would be consistent with the value you updated inside the synchronized block, also no guarantee if it would be a thread local cached value or from main memory. 因此,由于您在同步块外部引用了slot [0],因此无法保证此引用与您在同步块内部更新的值一致,也无法保证它是线程本地缓存的值还是来自线程的本地缓存的值。主内存。

BTW as @chrylis mentioned, your block is super expensive and you need to consider at least moving the wait() out. 顺便说一句,就像@chrylis提到的那样,您的代码块非常昂贵,您至少需要考虑将wait()移出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM