Jadual Kandungan
Pengenalan
1. Keperluan
2. Reka bentuk terperinci
2.1 Tentukan kunci
3、测试
Rumah Java javaTutorial Apakah struktur reka bentuk dan butiran kunci tulis semula Java

Apakah struktur reka bentuk dan butiran kunci tulis semula Java

Apr 18, 2023 pm 05:22 PM
java

    Pengenalan

    Sesetengah penemuduga suka meminta pelajar menulis semula kunci baharu selepas menerangkan prinsip kunci dan meminta mereka hadir di tempat kejadian . Tulis idea umum dan logik kod pada papan putih soalan temu bual ini secara peribadi saya fikir ia memfokuskan kepada dua bahagian:

    Periksa bagaimana pemahaman anda tentang prinsip kunci itu berlaku belum mentafsir kod sumber, anda hanya boleh membaca artikel dalam talian atau menghafal soalan temu duga, dan anda boleh memberitahu prinsip umum, tetapi sukar untuk anda menulis kod pelaksanaan kunci di tempat kejadian, melainkan anda benar-benar membaca kod sumber . Atau mempunyai pengalaman projek yang berkaitan dengan kunci;

    Kami tidak perlu mencipta, kami hanya perlu meniru dan menulis semula API sedia ada dalam kunci Java.

    Jika anda telah membaca kod sumber, soalan ini sangat mudah anda boleh memilih kunci yang anda biasa tiru.

    1. Keperluan

    Secara amnya, apabila menyesuaikan kunci, kami mentakrifkannya berdasarkan keperluan perkara. Senario, sebagai contoh, kunci baca pada sumber yang dikongsi boleh dikongsi, seperti akses dikongsi kepada pautan pangkalan data, contohnya, bilangan pautan pada pelayan Socket boleh dikongsi akses kepada pautan pangkalan data untuk menentukan Kunci.

    2. Reka bentuk terperinci

    Anggapkan (andaian berikut adalah semua andaian) bahawa pangkalan data kami adalah mysql yang berdiri sendiri, yang hanya boleh menanggung 10 sambungan apabila membuat pautan pangkalan data JDBC asal Dengan cara ini, kami menggunakan antara muka untuk merangkum proses mencipta pautan menggunakan JDBC Kami menamakan antara muka ini: buat antara muka pautan.

    Keperluan keseluruhan untuk pautan pangkalan data akses dikongsi adalah seperti berikut: bilangan pautan mysql untuk semua permintaan digabungkan tidak boleh melebihi 10 (termasuk apabila melebihi 10, ralat akan dilaporkan secara langsung).

    Dalam konteks ini, kami mereka bentuk gambar berikut:

    Apakah struktur reka bentuk dan butiran kunci tulis semula Java

    Bahagian paling kritikal dalam reka bentuk ini ialah sama ada kita boleh mendapatkan kunci melaluinya sama ada pautan mysql boleh diperoleh, jika kunci boleh diperoleh, maka pautan boleh diperoleh, jika tidak ralat akan dilaporkan terus.

    Kemudian mari kita lihat kod yang dilaksanakan:

    2.1 Tentukan kunci

    Mula-mula kita perlu menentukan kunci, yang memerlukan dua elemen:

    <.>Takrifan kunci: Penyegerakan penyegerak; kaedah mengunci dan membuka kunci yang disediakan oleh kunci kepada dunia luar.

    Pelaksanaan kod kunci kongsi adalah seperti berikut:

    // 共享不公平锁
    public class ShareLock implements Serializable{
    	// 同步器
      private final Sync sync;
      // 用于确保不能超过最大值
      private final int maxCount;
      /**
       * 初始化时给同步器 sync 赋值
       * count 代表可以获得共享锁的最大值
       */
      public ShareLock(int count) {
        this.sync = new Sync(count);
        maxCount = count;
      }
      /**
       * 获得锁
       * @return true 表示成功获得锁,false 表示失败
       */
      public boolean lock(){
        return sync.acquireByShared(1);
      }
      /**
       * 释放锁
       * @return true 表示成功释放锁,false 表示失败
       */
      public boolean unLock(){
        return sync.releaseShared(1);
      }
    }
    Salin selepas log masuk
    Seperti yang dapat dilihat daripada kod di atas, pelaksanaan mengunci dan melepaskan kunci bergantung pada pelaksanaan asas penyegerak Segerakkan.

    Satu-satunya perkara yang perlu diberi perhatian ialah kunci perlu menentukan spesifikasi API, terutamanya dalam dua aspek:

    Apa yang diperlukan oleh API ialah parameter yang anda perlu berikan kepada saya apabila kunci dimulakan Apabila memulakan ShareLock, anda perlu lulus bilangan maksimum kunci boleh kongsi

    perlu menentukan keupayaannya sendiri, iaitu, mentakrifkan parameter input dan parameter output bagi setiap kaedah. Dalam pelaksanaan ShareLock, tiada parameter input untuk mengunci dan melepaskan kunci Ia dikodkan dengan keras 1 dalam kaedah, yang bermaksud bahawa setiap kali kaedah itu dilaksanakan, kunci hanya boleh dikunci sekali atau dilepaskan parameter output ialah nilai Boolean, dan benar bermakna menambah Kunci atau pelepasan kunci berjaya, palsu menunjukkan kegagalan dan lapisan bawah menggunakan kunci tidak adil Segerak.

    Cara berfikir di atas mempunyai metodologi, iaitu apabila kita memikirkan sesuatu masalah, kita boleh bermula dari dua aspek: Apakah itu API? Apakah keupayaan yang ada pada API?

    2.2. Tentukan Penyegerakan penyegerak

    Penyegerakan terus mewarisi AQS, kodnya adalah seperti berikut:

    class Sync extends AbstractQueuedSynchronizer {
       // 表示最多有 count 个共享锁可以获得
      public Sync(int count) {
        setState(count);
      }
      // 获得 i 个锁
      public boolean acquireByShared(int i) {
        // 自旋保证 CAS 一定可以成功
        for(;;){
          if(i<=0){
            return false;
          }
          int state = getState();
          // 如果没有锁可以获得,直接返回 false
          if(state <=0 ){
            return false;
          }
          int expectState = state - i;
          // 如果要得到的锁不够了,直接返回 false
          if(expectState < 0 ){
            return false;
          }
          // CAS 尝试得到锁,CAS 成功获得锁,失败继续 for 循环
          if(compareAndSetState(state,expectState)){
            return true;
          }
        }
      }
      // 释放 i 个锁
      @Override
      protected boolean tryReleaseShared(int arg) {
        for(;;){
          if(arg<=0){
            return false;
          }
          int state = getState();
          int expectState = state + arg;
          // 超过了 int 的最大值,或者 expectState 超过了我们的最大预期
          if(expectState < 0 || expectState > maxCount){
            log.error("state 超过预期,当前 state is {},计算出的 state is {}",state
            ,expectState);
            return false;
          }
          if(compareAndSetState(state, expectState)){
            return true;
          }
        }
      }
    }
    Salin selepas log masuk
    Kod keseluruhannya agak jelas, apa yang perlu kita bayar perhatian ialah:

    Penghakiman sempadan, seperti sama ada parameter input adalah menyalahi undang-undang, sama ada akan dijangkakan keadaan menyalahi undang-undang semasa melepaskan kunci, dan isu sempadan lain Kita perlu menilai isu sedemikian untuk mencerminkan ketegasan berfikir;

    Untuk mengunci dan melepaskan kunci, anda perlu menggunakan bentuk untuk putaran + CAS untuk memastikan anda boleh mencuba semula dengan jayanya apabila mengunci atau melepaskan kunci secara serentak. Apabila menulis untuk putaran, kita perlu memberi perhatian untuk kembali pada masa yang sesuai dan tidak menyebabkan gelung tak terhingga Kaedah CAS telah disediakan oleh AQS. Kaedah CAS yang kita tulis sendiri tidak dapat menjamin atomicity.

    2.3 Sama ada pautan boleh diperolehi ditentukan oleh sama ada kunci boleh diperolehi

    Selepas kunci ditakrifkan, kita perlu menggabungkan kunci dengan mendapatkan pautan Mysql Kelas alat pautan Mysql , dipanggil MysqlConnection, yang bertanggungjawab terutamanya untuk dua fungsi utama:

    Mewujudkan pautan dengan Mysql melalui JDBC

    Digabungkan dengan kunci untuk mengelakkan jumlah pautan Mysql daripada melebihi; 10 apabila permintaan terlalu besar.

    Pertama, mari kita lihat kod permulaan MysqlConnection:

    public class MysqlConnection {
      private final ShareLock lock;
      // maxConnectionSize 表示最大链接数
      public MysqlConnection(int maxConnectionSize) {
        lock = new ShareLock(maxConnectionSize);
      }
    }
    Salin selepas log masuk
    Kita dapat melihat bahawa semasa permulaan, kita perlu menentukan bilangan maksimum pautan, dan kemudian hantar nilai ini kepada kunci, Kerana bilangan maksimum pautan ialah nilai keadaan kunci ShareLock.

    Kemudian untuk melengkapkan 1, kami menulis kaedah peribadi:

    // 得到一个 mysql 链接,底层实现省略
    private Connection getConnection(){}
    Salin selepas log masuk
    Kemudian kami melaksanakan 2, kodnya adalah seperti berikut:

    // 对外获取 mysql 链接的接口
    // 这里不用try finally 的结构,获得锁实现底层不会有异常
    // 即使出现未知异常,也无需释放锁
    public Connection getLimitConnection() {
      if (lock.lock()) {
        return getConnection();
      }
      return null;
    }
    // 对外释放 mysql 链接的接口
    public boolean releaseLimitConnection() {
      return lock.unLock();
    }
    Salin selepas log masuk

    逻辑也比较简单,加锁时,如果获得了锁,就能返回 Mysql 的链接,释放锁时,在链接关闭成功之后,调用 releaseLimitConnection 方法即可,此方法会把锁的 state 状态加一,表示链接被释放了。

    以上步骤,针对 Mysql 链接限制的场景锁就完成了。

    3、测试

    锁写好了,接着我们来测试一下,我们写了一个测试的 demo,代码如下:

    public static void main(String[] args) {
      log.info("模仿开始获得 mysql 链接");
      MysqlConnection mysqlConnection = new MysqlConnection(10);
      log.info("初始化 Mysql 链接最大只能获取 10 个");
      for(int i =0 ;i<12;i++){
        if(null != mysqlConnection.getLimitConnection()){
          log.info("获得第{}个数据库链接成功",i+1);
        }else {
          log.info("获得第{}个数据库链接失败:数据库连接池已满",i+1);
        }
      }
      log.info("模仿开始释放 mysql 链接");
      for(int i =0 ;i<12;i++){
        if(mysqlConnection.releaseLimitConnection()){
          log.info("释放第{}个数据库链接成功",i+1);
        }else {
          log.info("释放第{}个数据库链接失败",i+1);
        }
      }
      log.info("模仿结束");
    }
    Salin selepas log masuk

    以上代码逻辑如下:

    获得 Mysql 链接逻辑:for 循环获取链接,1~10 都可以获得链接,11~12 获取不到链接,因为链接被用完了;释放锁逻辑:for 循环释放链接,1~10 都可以释放成功,11~12 释放失败。

    我们看下运行结果,如下图:

    Apakah struktur reka bentuk dan butiran kunci tulis semula Java

    从运行的结果,可以看出,我们实现的 ShareLock 锁已经完成了 Mysql 链接共享的场景了。

    Atas ialah kandungan terperinci Apakah struktur reka bentuk dan butiran kunci tulis semula Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan Laman Web ini
    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

    Alat AI Hot

    Undresser.AI Undress

    Undresser.AI Undress

    Apl berkuasa AI untuk mencipta foto bogel yang realistik

    AI Clothes Remover

    AI Clothes Remover

    Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

    Undress AI Tool

    Undress AI Tool

    Gambar buka pakaian secara percuma

    Clothoff.io

    Clothoff.io

    Penyingkiran pakaian AI

    Video Face Swap

    Video Face Swap

    Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

    Alat panas

    Notepad++7.3.1

    Notepad++7.3.1

    Editor kod yang mudah digunakan dan percuma

    SublimeText3 versi Cina

    SublimeText3 versi Cina

    Versi Cina, sangat mudah digunakan

    Hantar Studio 13.0.1

    Hantar Studio 13.0.1

    Persekitaran pembangunan bersepadu PHP yang berkuasa

    Dreamweaver CS6

    Dreamweaver CS6

    Alat pembangunan web visual

    SublimeText3 versi Mac

    SublimeText3 versi Mac

    Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

    Nombor Sempurna di Jawa Nombor Sempurna di Jawa Aug 30, 2024 pm 04:28 PM

    Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

    Weka di Jawa Weka di Jawa Aug 30, 2024 pm 04:28 PM

    Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

    Nombor Smith di Jawa Nombor Smith di Jawa Aug 30, 2024 pm 04:28 PM

    Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

    Soalan Temuduga Java Spring Soalan Temuduga Java Spring Aug 30, 2024 pm 04:29 PM

    Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

    Cuti atau kembali dari Java 8 Stream Foreach? Cuti atau kembali dari Java 8 Stream Foreach? Feb 07, 2025 pm 12:09 PM

    Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

    TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

    Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.

    Program Java untuk mencari kelantangan kapsul Program Java untuk mencari kelantangan kapsul Feb 07, 2025 am 11:37 AM

    Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

    Cipta Masa Depan: Pengaturcaraan Java untuk Pemula Mutlak Cipta Masa Depan: Pengaturcaraan Java untuk Pemula Mutlak Oct 13, 2024 pm 01:32 PM

    Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.

    See all articles