Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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内存刷新volatile:一个好的程序设计?_Java_Multithreading_Design Patterns_Concurrency_Volatile - Fatal编程技术网

一个java内存刷新volatile:一个好的程序设计?

一个java内存刷新volatile:一个好的程序设计?,java,multithreading,design-patterns,concurrency,volatile,Java,Multithreading,Design Patterns,Concurrency,Volatile,这是一个与此相关的问题: 我有一个或多个不同的对象。我想更改其中的一些状态,然后我想使该状态对其他线程可见 出于性能原因,我不想让对象中的每个成员变量都是易变的。 有时我想在单线程应用程序中使用这些对象。因此,在这种情况下,波动性也会很差 所以我有以下几点: //these following mehtods change some internal variable state. These variables are not volatile or synchronized boolean

这是一个与此相关的问题:

我有一个或多个不同的对象。我想更改其中的一些状态,然后我想使该状态对其他线程可见

出于性能原因,我不想让对象中的每个成员变量都是易变的。 有时我想在单线程应用程序中使用这些对象。因此,在这种情况下,波动性也会很差

所以我有以下几点:

//these following mehtods change some internal variable state. These variables are not volatile or synchronized

boolean volatile memoryFlusher=false;

Thread1:

obj1->changeSomeState();
obj1->changeMoreState();
obj2->alsoSomeStateChange();

//and now i want to make that state visible to others

memoryFlusher=false; //volatile write


Thread2:

boolean tmp=memoryFlusher; // volatile read but variable is not used again

obj1->getState();
obj2->getState();
因此,到目前为止,我在一开始提到的相关问题或多或少都是一样的

现在我想问以下问题:

//these following mehtods change some internal variable state. These variables are not volatile or synchronized

boolean volatile memoryFlusher=false;

Thread1:

obj1->changeSomeState();
obj1->changeMoreState();
obj2->alsoSomeStateChange();

//and now i want to make that state visible to others

memoryFlusher=false; //volatile write


Thread2:

boolean tmp=memoryFlusher; // volatile read but variable is not used again

obj1->getState();
obj2->getState();
我的记忆过滤器没有优化?(我的另一个问题没有回答) 每个易失性写入/读取刷新所有的所有memoryState?其他(也非易失性)变量

现在真正新的问题是:

这是一个好的设计吗,我在那里做的? 因为我没有看到任何像这样的代码,我在这里发布

我应该用另一种方式编程吗? 是否有其他最佳实践来提高性能和获得可见性? 在程序设计视图中,没有这样的操作,还有其他最佳实践吗

编辑:

我更改的状态是未报告的。 所以我想用内存变量一个memoryflusher,没有锁机制。它应该将许多单个可变变量替换为一个。例如,我不需要显式的易失性内存刷新,因为我使用的是synchronized

synchronized(x)
{
    ...
    obj1->stateChange() //if internally is used a volatile, then i have a volatile memory flush and later the synchronized-end memory-flush, i guess (is that right?)
    ...
}
这将是一个例子,在那里它可能是有用的

总结:
但是这是正确的吗?我认为这样使用内存刷新?

您的易失性读写没有得到优化,但是我看不出这段代码有任何用处。这可能就是你在别处看不到它的原因。你没有说你期望从中得到什么,所以谁知道呢

看起来您希望确保Thread2可靠地读取Thread1所做的状态更改。好的,只有当您确定Thread2中的代码实际上在Thread1中的代码之后运行时,这才有效

你怎么知道是这样的

我建议,如果真的有任何方法可以确保Thread2代码发生在Thread1代码之后,那么已经有了一个内存屏障来确定这一事实,并使volatile变量变得不必要

我的记忆过滤器没有优化

否,写入和读取
内存刷新器
不会被优化

每个易失性写/读都会刷新所有内存的所有memoryState

是的,它会将内存同步到两个线程。但是,只有当您能够检测到从一个线程到另一个线程的更改时,它才起作用

在您的示例中,您读取了
memoryFlusher
,但初始化时
memoryFlusher
false
。您如何知道线程1实际写入了它?如果线程1位于此行
obj1->changeMoreState
,线程2读取
memoryFlusher
,该怎么办。这两个值在这里都是
false
,因此您不知道线程1是否实际完成。您不同步,因为您在订购之前还没有确定您的线程

要更正代码,应将
true
写入
memoryFlusher
字段,只有
memoryFlusher
为true时,线程2才应继续。这有效地建立了您的顺序,但也使您的代码更加混乱


我建议用一个代替这个的。当写操作不频繁时,StampedLock可以让您快速读取

所以你的意思是,我不应该只把这个MemoryFluser用作一个MemoryFluser,更像是一个信号变量?如果(memoryFlusher==true){…}在第二个线程中?首先解释您试图使用此代码完成什么OK,但是如果Thread1再次更改状态,则我的signalvariable已经为true;在这种情况下,我必须在Thread2中再次使signalvariable无效,对吗?但是在Thread2中,我应该在哪里再次将memoryFlusher设置为false?或者我应该在这里使用布尔值以外的其他值?为什么那样更让人困惑?
为什么那样更让人困惑?
你刚才说的确切原因。也许混淆不是正确的术语,我可以更新它。这只会使代码更加难以推理,并且在您的用例中出现错误。就您的观点而言(这是一个很好的观点),如果线程1再次更改了该值怎么办?好吧,你运气不好,无法建立订单。您的代码只能执行一次。在这种情况下,
StampedLock
更有意义。要安全地更新这些字段,可以多次使用
StampedLock
。好的,我想了几分钟:如果对象中的状态不相关,那么我不需要知道thread1何时更改这些值。Thread2可以看到该值本身的更改。您提到的StampedLock与内部CAS操作同步的java相同,对吗?因此,在这种情况下,我得到了与锁定视图中的java synchronized相同的StampedLocks行为。但我猜存在我不想锁定状态的场景(如果状态不相关)。还是我现在有思维问题^^