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

Heim >Java >javaLernprogramm >Beispielanalyse zweier Java-Threads, die einer Variablen 1 hinzufügen

Beispielanalyse zweier Java-Threads, die einer Variablen 1 hinzufügen

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBnach vorne
2023-04-28 21:52:191216Durchsuche

1 – Falsche konventionelle Schreibweise

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

Die Ergebnisse sind jedes Mal inkonsistent. In einer Multithread-Umgebung führt t1 eine +1-Operation für i im gemeinsam genutzten Speicher aus, aktualisiert jedoch nicht den Wert im Hauptspeicher. Zu diesem Zeitpunkt führt t2 zufällig auch eine aus +1-Operation, ob i 0 ist oder nicht, sodass das Endergebnis i alle 1 ist. Auf die gleiche Weise ist t1 nach der Verarbeitung 1 und t2 nach der Verarbeitung 2. Die Ergebnisse mehrerer Durchläufe sind inkonsistent.

Verbesserungsmethode 1 – Synchronisationssperre

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

Vorteile: einfache Implementierung

Nachteile: große Sperrgranularität, geringe Leistung, verteilte Umgebung, mehrere JVM-Bedingungen, synchronisierter Fehler, synchronisiert ist nur eine lokale Sperre und in einem verteilten Szenario werden nur Objekte unter der aktuellen JVM gesperrt. Verwenden Sie eine verteilte Sperre

Verbesserte Methode 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();    }}

Verbesserungsmethode 3 Schloss

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

Verteilte Sperre: Stellen Sie die gleichzeitige Ausführung mehrerer Knoten sicher
Implementierungsplan: 1. Basierend auf der Datenbank, 2. Basierend auf dem Redis-Cache, 3. Basierend auf zookeeper

Das obige ist der detaillierte Inhalt vonBeispielanalyse zweier Java-Threads, die einer Variablen 1 hinzufügen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen