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

ホームページ  >  記事  >  Java  >  変数に 1 を加算する 2 つの Java スレッドの分析例

変数に 1 を加算する 2 つの Java スレッドの分析例

WBOY
WBOY転載
2023-04-28 21:52:191147ブラウズ

1--従来の間違った書き方

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

結果は毎回一貫性がありません。マルチスレッド環境では、t1 は共有メモリ内の i に対して 1 操作を実行しますが、値をメイン メモリにリフレッシュしません。このとき、t2 はたまたま同様に、処理後の t1 は 1、処理後の t2 は 2 になります。複数の実行の結果に一貫性がありません。

改善方法1 --同期ロック

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

長所: 実装が簡単

短所: ロックの粒度が大きい、パフォーマンスが低い、分散環境、複数の JVM 条件、同期の失敗、同期はローカル ロックのみ、ロックはのみ現在のもの jvm 下のオブジェクトの場合、分散シナリオでは分散ロックを使用する必要があります

改善方法 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();    }}

改善方法3 ロック

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

分散ロック: 複数ノードの同期実行を保証します
実装計画: 1.データベースに基づく、2. Redis キャッシュに基づく、3. Zookeeper に基づく

以上が変数に 1 を加算する 2 つの Java スレッドの分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。