Saya tertanya-tanya adakah pelajar pernah mengalami temu duga sebegini:
Penemuduga: Sila bincang tentang mekanisme CAS secara serentak Xiao Ming: Baiklah, CAS, kan? Fikirkanlah (otak berfikir dengan pantas)
2 minit telah berlalu... Udara sunyi sepi...
Penemuduga tidak boleh duduk diam dan berdehem: Ehem... Itu, Boleh awak beritahu saya secara ringkas? Xiao Ming tersenyum naif: Hehe, saya macam terlupa... Penemuduga: Oh, tak apa, itu sahaja untuk temuduga hari ini, awak balik dan tunggu pemberitahuan Xiao Ming pergi dengan sedih...
don't Laugh, Xiao Ming sebenarnya bayang -bayang banyak orang. Foundation tak kukuh!
Maka persoalannya, bagaimana untuk mengalahkan penemuduga dalam temuduga dan menjadi stabil seperti batu?
Belajar! Apa gunanya hanya bercakap? Anda perlu belajar, anda perlu membaca buku yang anda beli, dan anda perlu mengikuti kursus yang anda beli. Jangan hanya bermain dan mengikuti drama TV kena botak!
Sekarang 0:08 waktu Beijing Saya sedang menulis artikel dalam kod, bagaimana dengan anda?
Sebuah contoh kecil untuk bercakap tentang apa itu keselamatan benang
Concurrency adalah asas pengaturcaraan Java Dalam kerja harian kita, kita sering berurusan dengan concurrency. Sudah tentu, ini juga diuji temu bual. Dalam pengaturcaraan serentak, konsep yang paling banyak disebut ialah线程安全Mari kita lihat sekeping kod untuk melihat apa yang berlaku selepas dijalankan:
public class Test { private static int inc = 0; public static void main(String[] args) { // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值 CountDownLatch countDownLatch = new CountDownLatch(1000000); // 设置100个线程同时执行 for (int i = 0; i < 100; i++) { new Thread(() -> { // 循环10000次,对inc实现 +1 操作 for (int j = 0; j < 10000; j++) { inc++; countDownLatch.countDown(); } }).start(); } try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } // 运行完毕,期望获取的结果是 1000000 System.out.println("执行完毕,inc的值为:" + inc); } }
Salin selepas log masuk
Dalam program ini, saya mencipta 100 utas dan berkongsi pembolehubah dalam setiap utasincmelakukan operasi terkumpul 10,000 kali. Jika ia dilaksanakan secara serentak, nilai akhir inc hendaklah 1,000,000, tetapi kita tahu bahawa dalam berbilang benang, atur cara dilaksanakan serentak, yang bermaksud berbeza Benang mungkin membaca nilai yang sama daripada memori utama pada masa yang sama, seperti senario ini:inc进行累加10000次的操作,如果是同步执行的话,inc最终的值应该是1000000,但我们知道在多线程中,程序是并发执行的,也就是说不同的线程可能会同时读取到主内存相同的值,比如这样的场景:
Benang A membaca nilai inc memori utama sebagai 1000 pada masa tertentu. Ia menambahkan 1 pada memori kerjanya sendiri dan inc menjadi 1001;
Thread B membaca nilai inc memori utama sebagai 1000 pada masa yang sama, dan ia juga Tambahkan 1 pada nilai inc dalam memori kerja anda sendiri, dan inc menjadi 1001; : 26px;color: rgb(1, 1, 1);">Apabila mereka ingin menulis nilai inc ke memori utama, mereka tidak melakukan sebarang kawalan penyegerakan, jadi mereka semua boleh menulis 1001 memori kerja mereka ke Utama memori;
Kemudian adalah jelas bahawa selepas memori utama melakukan dua operasi +1, hasil sebenar hanya melakukan +1 sekali dan menjadi 1001.
Ini adalah masalah yang sangat biasa yang disebabkan oleh berbilang benang yang mengubah suai pembolehubah yang dikongsi secara serentak 1000000:
public class Test { private static int inc = 0; public static void main(String[] args) { // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值 CountDownLatch countDownLatch = new CountDownLatch(1000000); // 设置100个线程同时执行 for (int i = 0; i < 100; i++) { new Thread(() -> { // 循环10000次,对inc实现 +1 操作 for (int j = 0; j < 10000; j++) { // 设置同步机制,让inc按照顺序执行 synchronized (Test.class) { inc++; } countDownLatch.countDown(); } }).start(); } try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("执行完毕,inc的值为:" + inc); } }
Salin selepas log masuk
Salin selepas log masuk
Sesetengah orang berkata sebelum 27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112 , 96);">mudah meruap
kata kunci boleh menyelesaikan masalah ini, kerana tidak menentu boleh memastikan keterlihatan antara benang, yang bermaksud bahawa benang boleh membaca nilai pembolehubah terkinidalam memori utama dan kemudian beroperasi padanya. Nota, tidak menentu hanya boleh menjamin
Keterlihatan kod>, dan tidak boleh menjamin operasi benangAtomicity, walaupun urutan membaca nilai terkini inc dalam memori utama,
Baca,
inc+1 code>, Write to main memory< /code> is a operasi tiga langkah, jadi tidak menentu tidak dapat menyelesaikan masalah keselamatan benang pembolehubah yang dikongsi. Jadi bagaimana untuk menyelesaikan masalah ini? Java menyediakan kami dengan penyelesaian berikut.
几种保证线程安全的方案
1. 通过synchronized关键字实现同步:
public class Test { private static int inc = 0; public static void main(String[] args) { // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值 CountDownLatch countDownLatch = new CountDownLatch(1000000); // 设置100个线程同时执行 for (int i = 0; i < 100; i++) { new Thread(() -> { // 循环10000次,对inc实现 +1 操作 for (int j = 0; j < 10000; j++) { // 设置同步机制,让inc按照顺序执行 synchronized (Test.class) { inc++; } countDownLatch.countDown(); } }).start(); } try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("执行完毕,inc的值为:" + inc); } }
private volatile int value; /** * Creates a new AtomicInteger with the given initial value. * * @param initialValue the initial value */ public AtomicInteger(int initialValue) { value = initialValue; } /** * Gets the current value. * * @return the current value */ public final int get() { return value; }
Salin selepas log masuk
一路跟踪incrementAndGet方法到的末尾可以看到是一个native的方法:
/** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; } // getAndAddInt 方法 public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; } // compareAndSet方法 public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
Sebagai pelaksanaan penguncian optimistik, apabila berbilang benang bersaing sengit untuk mendapatkan sumber, berbilang benang akan berputar dan menunggu, yang akan menggunakan sejumlah sumber CPU.
CAS pasti akan mengalami masalah ABA Untuk penjelasan dan penyelesaian masalah ABA, anda boleh merujuk artikel saya ini: Penemuduga bertanya kepada anda: Adakah anda tahu apa itu masalah ABA?
Baiklah, kali ini perkongsian tentang CAS berakhir di sini.Sebagai asas pengaturcaraan Java, concurrency adalah titik pengetahuan yang sangat penting Jika pelajar mempunyai pemahaman yang lemah tentang topik ini, saya berharap selepas membaca artikel itu, saya boleh menaip kod itu sendiri dan memikirkan apa itu CAS dan apakah itu. kelebihan dan kekurangannya ialah , apakah kaedah pelaksanaannya.Sudah tentu, concurrency adalah konsep yang sangat besar Di sini hanyalah pengenalan kecil, menyebut salah satu mata pengetahuan kecil, dan memberikan beberapa pengalaman pembelajaran saya sendiri.Sekiranya ada apa-apa yang tidak diterangkan dengan betul atau salah, sila hantar mesej peribadi kepada saya untuk membincangkannya bersama, terima kasih! . , di sini kami akan membantu anda mempelajari dan meringkaskan pengetahuan berkaitan Java berdasarkan temu bual sebenar setiap hari, membantu anda mengembangkan timbunan teknologi anda dan meningkatkan kekuatan peribadi anda. Jumpa lagi di lain kali~
Atas ialah kandungan terperinci Soalan temu bual sebenar: Sila bincangkan tentang mekanisme CAS secara serentak. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn