Thread has its own copy of data?

我只是一个虾纸丫 提交于 2020-07-20 03:41:08

问题


I have read somewhere that every threads have its own copy of shared states, even if I'm using synchronized or locks for modifying the variables, what guarantees that the changed state will be flushed into the main memory rather than in thread's own cache memory.

I know volatile guarantees and justifies the above scenario, even I know synchronized justifies too.

How does synchronized guarantees that changing the value is happening in the main memory rather than thread cache memory.

Ex Thread 1

synchronized(this)
{
int a = 0;
a = 5;
}  ----> the value might got changed in thread's cache memory another thread entering the block could read a value as 0

volatilte int a = 0;
a = 5; ----> another executing thread will read a values as 5

回答1:


You have to reason in terms of happens-before when thinking about multi-threaded code in java, this is what the JLS uses and this is what you should use. Period.

Going to your example, you munch volatile and synchronized together as if they do the same thing, sort of - they don't. Even your example is broken, for the "other" thread to see a guaranteed a = 5 it must synchronize on the same lock, which you don't. A jcstress test proves you wrong (I'll let you figure out how to run this exactly)

@JCStressTest
@State
@Outcome(id = "1, 0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "SURPRISE")
@Outcome(id = "0, 1", expect = Expect.ACCEPTABLE, desc = "whatever")
@Outcome(id = "0, 0", expect = Expect.ACCEPTABLE, desc = "whatever")
@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE, desc = "whatever")
public class DifferentSynchronizedObjects {

    int x, y;
    private Object lock = new Object();

    @Actor
    public void actor1() {
        synchronized (lock) {
            x = 1;
            y = 1;
        }
    }

    @Actor
    public void actor2(II_Result r) {
        r.r1 = x;
        r.r2 = y;
    }
} 

Even if you do not understand the code, it's main "selling point" is this:

@Outcome(id = "1, 0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "SURPRISE")

You can read it as : "while you were in the synchronized(lock){....}, some other thread came and read x and y". That reading thread saw 1, 0 (x = 1, y = 0) and now think about it. You were in the synchronized block, how come some thread read x = 1 and y = 0, aren't you "protected"? No you are not. If you run this - you will get 1, 0.

EDIT to answer the comment

You think you are protecting both writes to x and y - but since the JLS makes no such guarantees, it's your understanding of things, which is wrong. As simple as that. The only protection you actually get is if your writer and reader would use the same lock.

An optimizer might "see" that you are using that lock only inside a method, and as such transform that code to (in theory at least):

@Actor
public void actor1() {

    Object lock = new Object(); // < --  make lock local       

    synchronized (lock) {
        x = 1;
        y = 1;
    }
}

Since the lock is now local to a method what is the point in having it at all? No one can access it, and simply elide it entirely. Thus you get a totally unprotected code that performs two independent writes.

The conclusion is : you do not follow the rules that the JLS gives you - be prepared to get weird results.




回答2:


Without the use of the synchronized keyword (or volatile one) there is no guarantee that when one thread changes the value of a variable shared with other threads, that the other threads can see the changed value. There are no guarantees about when a variable kept in a CPU register by one thread is "committed" to main memory, and there is no guarantee about when other threads "refresh" a variable kept in a CPU register from main memory.

With synchronized keyword when a thread enters a sync block it will refresh the values of all variables visible to the thread(on the same lock/object). When a thread exits a synchronized block all changes to variables visible to the thread and for the same lock will be pushed/updated to main memory. It is actually the same as volatile works.



来源:https://stackoverflow.com/questions/61235213/thread-has-its-own-copy-of-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!