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

首頁  >  文章  >  Java  >  java兩個執行緒對變數進行加1操作實例分析

java兩個執行緒對變數進行加1操作實例分析

WBOY
WBOY轉載
2023-04-28 21:52:191145瀏覽

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也對i取到還是0進行1操作,使得最後結果i都為1,同理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條件,synchronized失效,synchronized 只是本地鎖,鎖的也只是當前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  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>

分散式鎖定:保證多個節點同步執行
實作方案:1。基於資料庫,2.基於redis緩存,3.基於zookeeper

以上是java兩個執行緒對變數進行加1操作實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除