Multithreading - Question about Java memory visibility
漂亮男人
漂亮男人 2017-05-17 10:06:58
0
4
843

Please see the following code

public class TestVolatile { public static void main(String[] args) throws InterruptedException { ThreadDemo td = new ThreadDemo(); new Thread(td).start(); Thread.sleep(1); while(true){ if(td.isFlag()){ System.out.println("------------------"); break; } } } } class ThreadDemo implements Runnable { private boolean flag = false; @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { } flag = true; System.out.println("flag=" + isFlag()); } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } }

ReplaceThread.sleep(1)withThread.sleep(1000)to get the modified value offlag, which istd .isFlag()returnstrue.
Although I have read the concept of Java memory model, I don't know how to explain this code.Who can explain it?

Related questions: What is the working memory of Java multi-threading?

漂亮男人
漂亮男人

reply all (4)
淡淡烟草味

You need to first tell me what your expected effect is? Ask questions clearly

    滿天的星座

    This expectation is not supported by standards. Nothing is done in the code to guarantee that "subthread writes happen-before main thread reads".

    sleep(1000)Seeing the modification later is just a coincidence. If a JVM waits longer for the main thread to see it, or even never lets the main thread see it, it does not violate the specification.

      刘奇

      Your program should be testedvolatile关键字的功能。但是 “把Thread.sleep(1)换成Thread.sleep(1000)就能获得预期效果” 这样做理解上是不对的。
      首先,程序中总共有两个线程,主线程(暂称 线程M)和new Thread(td)(tentatively called thread T).


      When writing the value ofThread.sleep(1)的时候,线程M 在 1ms 之后,便开始在while(true)循环中检查td.isFlag(), due to memory visibility, thread M cannot read the value offlagin thread T in time, so an infinite loop is caused at this time;


      When writingThread.sleep(1000), M starts to checktd.isFlag()in thewhile(true)loop after 1000ms. code>; but T sets the value ofThread.sleep(1000)的时候,M 在 1000ms 之后,开始在while(true)循环中检查td.isFlag()的值;但是 T 在 200ms 的时候,便将flag的值设为true了,所以,M 在 1000ms 之后检测td.isFlag()的值肯定是返回true的,那么第一次判断便会返回true,产生输出并跳出while(true)flag

      to trueat 200ms, so M detects td.isFlag()after 1000ms The value must return true, then the first judgment will return true, generate output and jump out of the while(true)loop.

      In order for thread M to read the value offlagin thread T in time,flagvolatileneeds to be modified with the

      keyword:

      private volatile boolean flag = false;
      Then every modification toflag volatilewill be immediately visible to other threads. Regarding the use of , you can refer to my blog: Java Multithreading (6): Use of volatile keyword
        大家讲道理

        You can refer to the following three codes:
        The first one is the same as your situation. Due to the visibility problem of multi-threading, it may cause an infinite loop.
        The second is to usesynchronizedto solve this problem. This is good for most work scenarios.synchronized解决此问题,大多数工作场景用这个好
        第三个是使用volatileThe third is to usevolatileto solve this problem, but this keyword only guarantees visibility. In actual scenarios, the limitations are relatively large, so use it with caution

        public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { @SuppressWarnings("unused") int i = 0; while(!stopRequested) { // System.out.println("加上这一句程序就可以终止,否则无限循环下去"); i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } }
        public class StopThread2 { private static boolean stopRequested; public static synchronized boolean getStopRequested() { return stopRequested; } public static synchronized void requestStop() { stopRequested = true; } public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { @SuppressWarnings("unused") int i = 0; while(!getStopRequested()/* stopRequested */) { i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop();/* stopRequested = true; */ } }
        public class StopThread3 { private static volatile boolean stopRequested; public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { @SuppressWarnings("unused") int i = 0; while(stopRequested) { i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } }
          Latest Downloads
          More>
          Web Effects
          Website Source Code
          Website Materials
          Front End Template
          About us Disclaimer Sitemap
          php.cn:Public welfare online PHP training,Help PHP learners grow quickly!