国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

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

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;
    }

}

Replace Thread.sleep(1) with Thread.sleep(1000) to get the modified value of flag, which is td .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 tested volatile 關(guān)鍵字的功能。但是 “把 Thread.sleep(1) 換成 Thread.sleep(1000) 就能獲得預(yù)期效果” 這樣做理解上是不對的。
首先,程序中總共有兩個線程,主線程(暫稱 線程M)和 new Thread(td) (tentatively called thread T).


When writing the value of Thread.sleep(1) 的時候,線程M 在 1ms 之后,便開始在 while(true) 循環(huán)中檢查 td.isFlag(), due to memory visibility, thread M cannot read the value of flag in thread T in time, so an infinite loop is caused at this time;


When writing Thread.sleep(1000), M starts to check td.isFlag() in the while(true) loop after 1000ms. code>; but T sets the value of Thread.sleep(1000) 的時候,M 在 1000ms 之后,開始在 while(true) 循環(huán)中檢查 td.isFlag() 的值;但是 T 在 200ms 的時候,便將 flag 的值設(shè)為 true 了,所以,M 在 1000ms 之后檢測 td.isFlag() 的值肯定是返回 true 的,那么第一次判斷便會返回 true,產(chǎn)生輸出并跳出 while(true)flag

to true at 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 of flag in thread T in time, flagvolatile needs to be modified with the

keyword:

private volatile boolean flag = false;
Then every modification to flagvolatile will 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 use synchronized to solve this problem. This is good for most work scenarios. synchronized解決此問題,大多數(shù)工作場景用這個好
第三個是使用volatileThe third is to use volatile to 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("加上這一句程序就可以終止,否則無限循環(huán)下去");
                    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