JavaRush /Java Blog /Random-ID /Rehat kopi #113. 5 hal yang mungkin belum Anda ketahui te...

Rehat kopi #113. 5 hal yang mungkin belum Anda ketahui tentang multithreading di Java. 10 Ekstensi JetBrains untuk Melawan Hutang Teknis

Dipublikasikan di grup Random-ID

5 Hal yang Mungkin Belum Anda Ketahui Tentang Multithreading di Java

Sumber: DZone Thread adalah jantung dari bahasa pemrograman Java. Bahkan menjalankan program Hello World memerlukan thread utama. Jika perlu, kita dapat menambahkan thread lain ke program jika kita ingin kode aplikasi kita lebih fungsional dan berkinerja. Jika kita berbicara tentang server web, maka ia memproses ratusan permintaan secara bersamaan. Beberapa utas digunakan untuk ini. Rehat kopi #113.  5 hal yang mungkin belum Anda ketahui tentang multithreading di Java.  10 Ekstensi JetBrains untuk Memerangi Hutang Teknis - 1Thread tidak diragukan lagi berguna, tetapi bekerja dengannya bisa jadi sulit bagi banyak pengembang. Pada artikel ini, saya akan membagikan lima konsep multithreading yang mungkin belum diketahui oleh pengembang baru dan berpengalaman.

1. Urutan program dan urutan eksekusi tidak cocok

Saat kita menulis kode, kita berasumsi bahwa kode tersebut akan dieksekusi persis seperti yang kita tulis. Namun kenyataannya tidak demikian. Kompiler Java dapat mengubah urutan eksekusi untuk mengoptimalkannya jika dapat menentukan bahwa output tidak akan berubah dalam kode single-threaded. Lihatlah cuplikan kode berikut:
package ca.bazlur.playground;

import java.util.concurrent.Phaser;

public class ExecutionOrderDemo {
    private static class A {
        int x = 0;
    }

    private static final A sharedData1 = new A();
    private static final A sharedData2 = new A();

    public static void main(String[] args) {
        var phaser = new Phaser(3);
        var t1 = new Thread(() -> {
            phaser.arriveAndAwaitAdvance();
            var l1 = sharedData1;
            var l2 = l1.x;
            var l3 = sharedData2;
            var l4 = l3.x;
            var l5 = l1.x;
            System.out.println("Thread 1: " + l2 + "," + l4 + "," + l5);
        });
        var t2 = new Thread(() -> {
            phaser.arriveAndAwaitAdvance();
            var l6 = sharedData1;
            l6.x = 3;
            System.out.println("Thread 2: " + l6.x);
        });
        t1.start();
        t2.start();
        phaser.arriveAndDeregister();
    }
}
Kode ini tampaknya sederhana. Kami memiliki dua contoh data bersama ( sharedData1 dan sharedData2 ) yang menggunakan dua thread. Ketika kita mengeksekusi kode tersebut, kita mengharapkan hasilnya seperti ini:
Benang 2: 3 Benang 1: 0,0,0
Namun jika Anda menjalankan kode tersebut beberapa kali, Anda akan melihat hasil yang berbeda:
Utas 2: 3 Utas 1: 3,0,3 Utas 2: 3 Utas 1: 0,0,3 Utas 2: 3 Utas 1: 3,3,3 Utas 2: 3 Utas 1: 0,3,0 Utas 2 : 3 Benang 1: 0,3,3
Saya tidak mengatakan bahwa semua streaming ini akan diputar persis seperti ini di mesin Anda, tetapi itu sangat mungkin.

2. Jumlah thread Java terbatas

Membuat thread di Java itu mudah. Namun, ini tidak berarti bahwa kita dapat membuat sebanyak mungkin yang kita suka. Jumlah thread terbatas. Kita dapat dengan mudah mengetahui berapa banyak thread yang dapat kita buat pada mesin tertentu menggunakan program berikut:
package ca.bazlur.playground;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;

public class Playground {
    public static void main(String[] args) {
        var counter = new AtomicInteger();
        while (true) {
            new Thread(() -> {
                int count = counter.incrementAndGet();
                System.out.println("thread count = " + count);
                LockSupport.park();
            }).start();
        }
    }
}
Program di atas sangat sederhana. Ini membuat thread dalam satu lingkaran dan kemudian memarkirnya, yang berarti thread tersebut dinonaktifkan untuk digunakan di masa mendatang tetapi melakukan panggilan sistem dan mengalokasikan memori. Program terus membuat thread hingga tidak dapat dibuat lagi, lalu memunculkan pengecualian. Kami tertarik dengan nomor yang akan kami terima hingga program mengeluarkan pengecualian. Di komputer saya, saya hanya mampu membuat 4065 thread.

3. Terlalu banyak thread tidak menjamin performa yang lebih baik

Adalah naif untuk percaya bahwa membuat thread menjadi mudah di Java akan meningkatkan kinerja aplikasi. Sayangnya, asumsi ini salah dengan model multithreading tradisional yang disediakan Java saat ini. Faktanya, terlalu banyak thread dapat menurunkan kinerja suatu aplikasi. Pertama mari kita ajukan pertanyaan ini: berapa jumlah maksimum thread optimal yang dapat kita buat untuk memaksimalkan kinerja aplikasi? Jawabannya tidak sesederhana itu. Hal ini sangat bergantung pada jenis pekerjaan yang kita lakukan. Jika kita memiliki beberapa tugas independen, yang semuanya bersifat komputasi dan tidak memblokir sumber daya eksternal apa pun, maka memiliki sejumlah besar thread tidak akan banyak meningkatkan kinerja. Sebaliknya, jika kita memiliki prosesor 8 inti, jumlah thread optimalnya adalah (8 + 1). Dalam kasus seperti itu, kita dapat mengandalkan thread paralel yang diperkenalkan di Java 8. Secara default, thread paralel menggunakan kumpulan Fork/Join bersama. Ini menciptakan thread yang setara dengan jumlah prosesor yang tersedia, yang cukup bagi mereka untuk bekerja secara intensif. Menambahkan lebih banyak thread ke pekerjaan intensif CPU di mana tidak ada yang diblokir tidak akan meningkatkan kinerja. Sebaliknya, kita hanya akan menyia-nyiakan sumber daya. Catatan. Alasan memiliki thread tambahan adalah karena thread yang memerlukan komputasi intensif terkadang menyebabkan kesalahan halaman atau ditangguhkan karena alasan lain. (Lihat: Java Parallelism in Practice , Brian Goetz, halaman 170) Namun, misalkan, tugas-tugas tersebut terikat pada I/O. Dalam hal ini, mereka bergantung pada komunikasi eksternal (misalnya database, API lain), sehingga jumlah thread yang lebih besar masuk akal. Alasannya adalah ketika sebuah thread menunggu di Rest API, thread lain dapat terus bekerja. Sekarang kita bisa bertanya lagi, berapa banyak thread yang terlalu banyak untuk kasus seperti itu? Bergantung. Tidak ada angka sempurna yang cocok untuk semua kasus. Oleh karena itu, kita harus melakukan pengujian yang memadai untuk mengetahui mana yang terbaik untuk beban kerja dan aplikasi spesifik kita. Dalam skenario yang paling umum, kami biasanya memiliki serangkaian tugas yang beragam. Dan dalam kasus seperti itu, segala sesuatunya akan selesai. Dalam bukunya “Java Concurrency in Practice,” Brian Goetz mengusulkan rumus yang dapat kita gunakan dalam banyak kasus. Jumlah thread = Jumlah Core yang Tersedia * (1 + Waktu tunggu / Waktu layanan) Waktu tunggu bisa berupa IO, seperti menunggu respons HTTP, memperoleh kunci, dan sebagainya. Waktu Pelayanan(Waktu layanan) adalah waktu komputasi, seperti pemrosesan respons HTTP, marshaling/unmarshaling, dan sebagainya. Misalnya, sebuah aplikasi memanggil API dan kemudian memprosesnya. Jika kita memiliki 8 prosesor di server aplikasi, waktu respons API rata-rata adalah 100 md, dan waktu pemrosesan respons adalah 20 md, maka ukuran thread yang ideal adalah:
N = 8 * ( 1 + 100/20) = 48
Namun, ini merupakan penyederhanaan yang berlebihan; pengujian yang memadai selalu penting untuk menentukan jumlahnya.

4. Multithreading bukanlah paralelisme

Terkadang kita menggunakan multithreading dan paralelisme secara bergantian, tetapi ini tidak lagi relevan. Meskipun di Java kita mencapai keduanya menggunakan thread, keduanya adalah hal yang berbeda. “Dalam pemrograman, multithreading adalah kasus khusus terlepas dari proses yang berjalan, dan paralelisme adalah eksekusi perhitungan (yang mungkin terkait) secara bersamaan. Multithreading adalah tentang berinteraksi dengan banyak hal secara bersamaan. Konkurensi melakukan banyak hal pada saat yang bersamaan.” Definisi yang diberikan oleh Rob Pike di atas cukup akurat. Katakanlah kita memiliki tugas yang sepenuhnya independen, dan tugas tersebut dapat dihitung secara terpisah. Dalam hal ini, tugas-tugas ini disebut paralel dan dapat dijalankan dengan kumpulan Fork/Join atau thread paralel. Sebaliknya, jika kita mempunyai banyak tugas, beberapa di antaranya mungkin bergantung pada tugas lainnya. Cara kita menyusun dan menyusun disebut multithreading. Ini ada hubungannya dengan struktur. Kita mungkin ingin melakukan beberapa tugas secara bersamaan untuk mencapai hasil tertentu, tanpa harus menyelesaikan satu tugas dengan lebih cepat.

5. Project Loom memungkinkan kita membuat jutaan thread

Pada poin sebelumnya, saya berpendapat bahwa memiliki lebih banyak thread tidak berarti meningkatkan kinerja aplikasi. Namun, di era layanan mikro, kita berinteraksi dengan terlalu banyak layanan untuk menyelesaikan pekerjaan tertentu. Dalam skenario seperti itu, sebagian besar thread tetap dalam keadaan diblokir. Meskipun OS modern dapat menangani jutaan soket terbuka, kita tidak dapat membuka banyak saluran komunikasi karena dibatasi oleh jumlah thread. Namun bagaimana jika Anda membuat jutaan thread, dan masing-masing thread menggunakan soket terbuka untuk berkomunikasi dengan dunia luar? Ini pasti akan meningkatkan throughput aplikasi kita. Untuk mendukung ide ini, ada inisiatif di Java yang disebut Project Loom. Dengan menggunakannya, kita dapat membuat jutaan thread virtual. Misalnya, dengan menggunakan cuplikan kode berikut, saya dapat membuat 4,5 juta thread di mesin saya.
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;

public class Main {
    public static void main(String[] args) {
        var counter = new AtomicInteger();

        // 4_576_279
        while (true) {
            Thread.startVirtualThread(() -> {
                int count = counter.incrementAndGet();
                System.out.println("thread count = " + count);
                LockSupport.park();
            });
        }
    }
}
Untuk menjalankan program ini Anda harus menginstal Java 18 yang dapat diunduh di sini . Anda dapat menjalankan kode menggunakan perintah berikut: java --source 18 --enable-preview Main.java

10 Ekstensi JetBrains untuk Melawan Hutang Teknis

Sumber: DZone Banyak tim pengembangan merasakan tekanan yang sangat besar untuk memenuhi tenggat waktu. Oleh karena itu, mereka sering kali tidak memiliki cukup waktu untuk memperbaiki dan membersihkan basis kodenya. Terkadang dalam situasi seperti ini, utang teknis dengan cepat terakumulasi. Ekstensi editor dapat membantu mengatasi masalah ini. Mari kita lihat 10 ekstensi JetBrains terbaik untuk memerangi utang teknis (dengan dukungan Java). Rehat kopi #113.  5 hal yang mungkin belum Anda ketahui tentang multithreading di Java.  10 Ekstensi JetBrains untuk Melawan Hutang Teknis - 2

Refactoring dan alat utang teknis

1. Wawasan Refaktor

RefactorInsight meningkatkan visibilitas perubahan kode di IDE dengan memberikan informasi tentang pemfaktoran ulang.
  1. Ekstensi ini mendefinisikan pemfaktoran ulang dalam permintaan penggabungan.
  2. Tandai komitmen yang berisi pemfaktoran ulang.
  3. Membantu dalam melihat pemfaktoran ulang komit tertentu yang dipilih di tab Git Log.
  4. Menampilkan riwayat pemfaktoran ulang kelas, metode, dan bidang.

2. Pelacak Masalah Ukuran Langkah di IDE

Stepsize adalah pelacak masalah yang bagus untuk pengembang. Ekstensi ini membantu para insinyur tidak hanya membuat TODO dan komentar kode yang lebih baik, namun juga memprioritaskan utang teknis, pemfaktoran ulang, dan sejenisnya:
  1. Stepsize memungkinkan Anda membuat dan melihat tugas dalam kode langsung di editor.
  2. Temukan masalah yang memengaruhi fitur yang sedang Anda kerjakan.
  3. Tambahkan masalah ke sprint Anda menggunakan integrasi Jira, Asana, Linear, Azure DevOps, dan GitHub.

3. CodeStream Peninggalan Baru

New Relic CodeStream adalah platform kolaborasi pengembang untuk berdiskusi dan meninjau kode. Ini mendukung permintaan tarik dari GitHub, BitBucket dan GitLab, manajemen masalah dari Jira, Trello, Asana dan 9 lainnya, dan menyediakan diskusi kode, menyatukan semuanya.
  1. Buat, tinjau, dan gabungkan permintaan tarik di GitHub.
  2. Dapatkan masukan tentang pekerjaan yang sedang berlangsung dengan tinjauan kode awal.
  3. Membahas masalah kode dengan rekan satu tim.

TODO dan komentar

4. Penyorot Komentar

Plugin ini memungkinkan Anda membuat penyorotan khusus pada baris komentar dan kata kunci bahasa. Plugin ini juga memiliki kemampuan untuk menentukan token khusus untuk menyorot baris komentar.

5. Komentar yang Lebih Baik

Ekstensi Better Comments membantu Anda membuat komentar yang lebih jelas dalam kode Anda. Dengan ekstensi ini Anda akan dapat mengklasifikasikan anotasi Anda menjadi:
  1. Peringatan.
  2. Permintaan.
  3. MELAKUKAN.
  4. Momen dasar.

Bug dan kerentanan keamanan

6.SonarLint _

SonarLint memungkinkan Anda memecahkan masalah kode sebelum masalah tersebut muncul. Ini juga dapat digunakan sebagai pemeriksa ejaan. SonarLint menyoroti bug dan kerentanan keamanan saat Anda membuat kode, dengan instruksi remediasi yang jelas sehingga Anda dapat memperbaikinya sebelum kode diterapkan.

7. SpotBug

Plugin SpotBugs menyediakan analisis bytecode statis untuk menemukan bug dalam kode Java dari IntelliJ IDEA. SpotBugs adalah alat pendeteksi cacat untuk Java yang menggunakan analisis statis untuk menemukan lebih dari 400 pola bug seperti dereferensi penunjuk nol, loop rekursif tak terbatas, penyalahgunaan perpustakaan Java, dan kebuntuan. SpotBugs dapat mengidentifikasi ratusan cacat serius dalam aplikasi besar (biasanya sekitar 1 cacat per 1000-2000 baris pernyataan mentah tanpa komentar).

8. Pemindai Kerentanan Snyk

Pemindai Kerentanan Snyk membantu Anda menemukan dan memperbaiki kerentanan keamanan dan masalah kualitas kode dalam proyek Anda.
  1. Menemukan dan memperbaiki masalah keamanan.
  2. Lihat daftar berbagai jenis masalah, dibagi ke dalam kategori.
  3. Menampilkan tip pemecahan masalah.

9. Pencari Karakter Lebar Nol

Plugin ini meningkatkan pemeriksaan dan deteksi kesalahan yang sulit ditemukan terkait dengan karakter lebar nol yang tidak terlihat dalam kode sumber dan sumber daya. Saat menggunakan, pastikan tanda centang "Karakter unicode lebar nol" diaktifkan.

10.KodeMR _

CodeMR adalah alat analisis kode statis dan kualitas perangkat lunak yang membantu perusahaan perangkat lunak mengembangkan kode dan program yang lebih baik. CodeMR memvisualisasikan metrik kode dan atribut kualitas tingkat tinggi (kopling, kompleksitas, kohesi, dan ukuran) dalam berbagai tampilan seperti Struktur Paket, TreeMap, Sunburst, Dependency, dan Graph Views.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION