"+Thread.currentThread().getName( )+":"+i);}publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1"/> "+Thread.currentThread().getName( )+":"+i);}publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1">

Maison >Java >javaDidacticiel >Exemple d'analyse de deux threads Java ajoutant 1 à une variable

Exemple d'analyse de deux threads Java ajoutant 1 à une variable

WBOY
WBOYavant
2023-04-28 21:52:191161parcourir

1--Mauvaise écriture conventionnelle

<code>public static int i=0;</code><code>public static void add(){</code><code>    i=i+1;</code><code>    action();</code><code>}</code><code>public static void action(){</code><code>    System.out.println("==>"+Thread.currentThread().getName()+":"+i);</code><code>}</code><code>public static void main(String[] args) throws InterruptedException {</code><code>    Thread t1 = new Thread(SysUserServiceImpl::add,"t1");</code><code>    Thread t2= new Thread(SysUserServiceImpl::add,"t2");</code><code>    t1.start();</code><code>    t2.start();</code><code>}</code><code>运行结果==></code><code>==>t1:1</code><code>==>t2:2</code><code><br></code><code>==>t1:2</code><code>==>t2:1</code><code><br></code><code>==>t1:2</code><code>==>t2:2</code>

Les résultats sont incohérents à chaque fois. Dans un environnement multithread, t1 effectue une opération +1 sur i dans la mémoire partagée, mais ne rafraîchit pas la valeur dans la mémoire principale. À ce moment, t2 effectue également une opération. Opération +1 pour savoir si i vaut 0 ou non. De sorte que le résultat final i soit entièrement 1. De la même manière, t1 vaut 1 après traitement et t2 vaut 2 après traitement. Les résultats de plusieurs exécutions sont incohérents.

Méthode d'amélioration 1 -- verrouillage de synchronisation

<code>public class ThreadException {</code><code>    public static volatile int i=0;</code><code>    public static void add(){</code><code>        synchronized (ThreadException.class){</code><code>            i=i+1;</code><code>            action();</code><code>        }</code><code>    }</code><code>    public static void action(){</code><code>        System.out.println("==>"+Thread.currentThread().getName()+":"+i);</code><code>    }</code><code>    public static void main(String[] args) throws InterruptedException {</code><code>        Thread t1 = new Thread(ThreadException::add,"t1");</code><code>        Thread t2= new Thread(ThreadException::add,"t2");</code><code>        t1.start();</code><code>        t2.start();</code><code><br></code><code>    }</code><code>}</code>

Avantages : implémentation simple

Inconvénients : grande granularité de verrouillage, faibles performances, environnement distribué, plusieurs conditions JVM, échec synchronisé, synchronisé n'est qu'un verrou local et seuls les objets sous la jvm actuelle sont verrouillés dans un scénario distribué, utiliser le verrouillage distribué

Méthode améliorée 2 AtomicInteger

public class ThreadException {    private static AtomicInteger num = new AtomicInteger(0);    public static void add(){        int i = num.getAndIncrement();        action(i);    }    public static void action(int i){        System.out.println("由"+i+"==>"+Thread.currentThread().getName()+":"+num);    }    public static void main(String[] args) throws InterruptedException {        Thread t1 = new Thread(ThreadException::add,"t1");        Thread t2= new Thread(ThreadException::add,"t2");        t1.start();        t2.start();    }}

Méthode d'amélioration 3 lock

<code>public class ThreadException {</code><code>    public static volatile int i=0;</code><code>    public static void action(){</code><code>        System.out.println("==>"+Thread.currentThread().getName()+":"+i);</code><code>    }</code><code><br></code><code>    static Lock lock=new ReentrantLock();</code><code>    public static void inc() {</code><code>        lock.lock();</code><code>        try {</code><code>            Thread.sleep(1);</code><code>            i=i+1;</code><code>            action();</code><code>        } catch (InterruptedException e) {</code><code>            e.printStackTrace();</code><code>        } finally {</code><code>            lock.unlock();</code><code>        }</code><code>    }</code><code>    public static void main(String[] args) throws InterruptedException {</code><code>        Thread t1 = new Thread(ThreadException::inc,"t1");</code><code>        Thread t2= new Thread(ThreadException::inc,"t2");</code><code>        t1.start();</code><code>        t2.start();</code><code>    }</code><code>}</code><code><br></code>

Verrouillage distribué : assurer l'exécution simultanée de plusieurs nœuds
Plan de mise en œuvre : 1. Basé sur la base de données, 2. Basé sur le cache Redis, 3. Basé sur zookeeper

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer