In the Java memory model (JMM) in the Java Language Specification, if thread A writes a field and then unlocks a mutex, the write "happens before" the unlock. That means that two threads sharing a variable only while using the same synchronization block or mutex do not need that variable to be volatile for their changes to be visible, because the shared mutex will create a memory barrier.
Is the same thing true for C++?
Consider this code
std::mutex m;
int x = 0;
std::cout << "Starting async:\n";
auto future1 = async(launch::async,
[&] { for (int i = 0; i < 100000; ++i) { m.lock(); ++x; m.unlock(); } });
auto future2 = async(launch::async,
[&] { for (int i = 0; i < 100000; ++i) { m.lock(); ++x; m.unlock(); } });
std::cout << "After calling async. Waiting for result from async:\n";
future1.get(); // wait for thread1
future2.get(); // wait for thread1
std::cout << "x = " << x;
does X still need to be declared volatile in order for one thread to see the most recent change created by the other thread?