Also the programs are not direct translations of each other - a direct translation to Java would use varhandle and opaque (equivalent to relaxed), and then would not contain a data race.

Wait, what? How would you translate the Java code I wrote to C++ then?

You can't precisely convert it to c++, because there's no c++ construct that precisely matches Java behavior - namely atomic with relaxed memory order but permitting aliasing and load/store optimizations. The spiritually closest thing would just be a regular variable, which would be a data race that tsan would catch.

You can go the other way, porting that c++ to Java using varhandle and opaque memory order.