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 サイトの他の関連記事を参照してください。