1--Tulisan konvensional yang salah
<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>
Hasil setiap operasi tidak konsisten Dalam persekitaran berbilang benang, t1 melakukan operasi +1 pada i dalam memori kongsi, tetapi tidak menyegarkan nilai ke memori utama pada masa ini, t2 kebetulan juga memperoleh i atau 0. Operasi +1 menjadikan keputusan akhir i semua menjadi 1. Dengan cara yang sama, t1 ialah 1 selepas pemprosesan, dan t2 ialah 2 selepas pemprosesan. Keputusan beberapa larian adalah tidak konsisten.
Kaedah penambahbaikan 1 -- kunci penyegerakan
<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>
Kelebihan: pelaksanaan mudah
Kelemahan: butiran penguncian yang besar, prestasi rendah, persekitaran teragih, berbilang keadaan JVM, kegagalan disegerakkan, disegerakkan hanyalah kunci tempatan dan kunci itu hanya yang semasa Untuk objek di bawah jvm, dalam senario teragih, kunci teragih
Kaedah Penambahbaikan 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(); }}
Kaedah penambahbaikan 3 kunci
<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>
Kunci teragih: pastikan pelaksanaan segerak berbilang nod
Pelan pelaksanaan: 1. Berdasarkan pangkalan data, 2. Berdasarkan cache redis, 3. Berdasarkan zookeeper
Atas ialah kandungan terperinci Contoh analisis dua utas Java menambah 1 pada pembolehubah. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!