亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Multithreading - Question sur la visibilité de la mémoire en Java
漂亮男人
漂亮男人 2017-05-17 10:06:58
0
4
1075

Veuillez consulter le code suivant

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

}

Mettez Thread.sleep(1)換成Thread.sleep(1000)就能獲取flag修改后的值,即td.isFlag()返回true.
Bien que j'ai lu le concept de modèle de mémoire Java, je ne sais pas comment interpréter ce code Qui peut l'expliquer ?

Question connexe?: quelle est la mémoire de travail du multi-threading Java??

漂亮男人
漂亮男人

répondre à tous(4)
淡淡煙草味

Vous devez d'abord me dire quel est votre effet attendu ? Posez des questions clairement

滿天的星座

Cette attente n’est pas prise en charge par les normes. Rien n'est fait dans le code pour garantir que "les écritures du sous-thread se produisent avant la lecture du thread principal".

sleep(1000)Voir la modification plus tard n'est qu'une co?ncidence. Si une JVM attend plus longtemps que le thread principal la voie, ou même ne laisse jamais le thread principal la voir, elle ne viole pas la spécification.

劉奇

Votre programme devrait vouloir tester la fonctionnalité du mot-clé volatile. Mais "remplacer Thread.sleep(1) par Thread.sleep(1000) obtiendra l'effet souhaité" n'est pas une compréhension correcte.
Tout d'abord, il y a deux threads dans le programme, le thread principal (appelé provisoirement thread M) et le new Thread(td) (appelé provisoirement thread T). volatile 關(guān)鍵字的功能。但是 “把 Thread.sleep(1) 換成 Thread.sleep(1000) 就能獲得預(yù)期效果” 這樣做理解上是不對(duì)的。
首先,程序中總共有兩個(gè)線程,主線程(暫稱 線程M)和 new Thread(td) (暫稱 線程T)。


當(dāng)寫(xiě) Thread.sleep(1) 的時(shí)候,線程M 在 1ms 之后,便開(kāi)始在 while(true) 循環(huán)中檢查 td.isFlag() 的值,但是因?yàn)閮?nèi)存可見(jiàn)性的關(guān)系,線程M 并不能及時(shí)讀取 線程T 中 flag 的值,所以此時(shí)導(dǎo)致了死循環(huán);


當(dāng)寫(xiě) Thread.sleep(1000) 的時(shí)候,M 在 1000ms 之后,開(kāi)始在 while(true) 循環(huán)中檢查 td.isFlag() 的值;但是 T 在 200ms 的時(shí)候,便將 flag 的值設(shè)為 true 了,所以,M 在 1000ms 之后檢測(cè) td.isFlag() 的值肯定是返回 true 的,那么第一次判斷便會(huì)返回 true,產(chǎn)生輸出并跳出 while(true) 循環(huán)。


為了讓 線程M 及時(shí)讀取到 線程T 中 flag 的值,需要將 flag 使用 volatile 關(guān)鍵字進(jìn)行修飾:

private volatile boolean flag = false;

那么每次對(duì) flag 的修改,其他線程都立馬可見(jiàn)。關(guān)于 volatile


Lors de l'écriture de Thread.sleep(1), le thread M commence à vérifier td.isFlag() dans la boucle while(true) après 1 ms , mais en raison de la visibilité de la mémoire, le thread M ne peut pas lire la valeur du flag dans le thread T à temps, donc une boucle infinie est provoquée à ce moment????;
??Lors de l'écriture de Thread.sleep(1000), M commence à vérifier td.isFlag() dans la boucle while(true) après 1000 ms de code >; mais T définit la valeur de flag sur true à 200 ms, donc M détecte td.isFlag( après 1000 ms) doit renvoyer true, alors le premier jugement renverra true, générera une sortie et sortira de la boucle while(true) code>. ??
??Pour que le thread M puisse lire la valeur de flag dans le thread T à temps, flag doit être modifié avec le mot-clé volatile?: ?? rrreee ??Ensuite, chaque modification apportée au flag sera immédiatement visible par les autres discussions. Concernant l'utilisation de volatile, vous pouvez vous référer à mon blog : Java Multithreading (6) : Utilisation du mot clé volatile ??
大家講道理

Vous pouvez vous référer aux trois codes suivants :
Le premier est le même que votre situation En raison du problème de visibilité du multi-thread, cela peut provoquer une boucle infinie.
La deuxième consiste à utiliser synchronized pour résoudre ce problème. synchronized解決此問(wèn)題,大多數(shù)工作場(chǎng)景用這個(gè)好
第三個(gè)是使用volatileLa troisième consiste à utiliser volatile pour résoudre ce problème, mais ce mot-clé uniquement. garantit la visibilité. Dans les scénarios réels, les limitations sont relativement importantes, alors utilisez-le avec prudence

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("加上這一句程序就可以終止,否則無(wú)限循環(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;
    }
}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal