Rumah  >  Artikel  >  Java  >  Pemahaman mendalam tentang prinsip berbilang benang Java: daripada mekanisme penjadualan kepada pengurusan sumber yang dikongsi

Pemahaman mendalam tentang prinsip berbilang benang Java: daripada mekanisme penjadualan kepada pengurusan sumber yang dikongsi

WBOY
WBOYasal
2024-02-22 23:42:03948semak imbas

Pemahaman mendalam tentang prinsip berbilang benang Java: daripada mekanisme penjadualan kepada pengurusan sumber yang dikongsi

Pemahaman mendalam tentang prinsip berbilang benang Java: daripada mekanisme penjadualan kepada pengurusan sumber dikongsi

Pengenalan:
Dalam pembangunan aplikasi komputer moden, pengaturcaraan berbilang benang telah menjadi corak pengaturcaraan biasa. Sebagai bahasa pengaturcaraan yang biasa digunakan, Java menyediakan API yang kaya dan mekanisme pengurusan benang yang cekap dalam pengaturcaraan berbilang benang. Walau bagaimanapun, pemahaman mendalam tentang prinsip multithreading Java adalah penting untuk menulis program multithreading yang cekap dan boleh dipercayai. Artikel ini akan meneroka prinsip Java multi-threading daripada mekanisme penjadualan kepada pengurusan sumber dikongsi, dan mendalami pemahaman melalui contoh kod tertentu.

1. Mekanisme penjadualan:
Dalam pengaturcaraan berbilang benang Java, mekanisme penjadualan adalah kunci untuk mencapai pelaksanaan serentak. Java menggunakan strategi penjadualan awalan Apabila berbilang utas dijalankan pada masa yang sama, CPU akan menentukan masa yang diperuntukkan kepada setiap utas berdasarkan faktor seperti keutamaan, potongan masa dan masa menunggu utas.

Mekanisme penjadualan thread Java boleh dikawal melalui kaedah kelas Thread, seperti tetapan keutamaan thread, tidur dan bangun, dsb. Berikut ialah contoh mudah:

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread is running");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        thread1.setPriority(Thread.MIN_PRIORITY);
        thread2.setPriority(Thread.MAX_PRIORITY);
        thread1.start();
        thread2.start();
    }
}

Dalam contoh di atas, dua objek utas dicipta, keutamaan berbeza ditetapkan masing-masing, dan kemudian utas dimulakan melalui kaedah mula(). Memandangkan urutan larian benang tidak pasti, keputusan setiap larian mungkin berbeza.

2. Penyegerakan benang dan pengecualian bersama:
Dalam pengaturcaraan berbilang benang, terdapat masalah akses kepada sumber yang dikongsi. Apabila berbilang rangkaian mengakses sumber yang dikongsi pada masa yang sama, masalah seperti keadaan perlumbaan dan ketidakkonsistenan data mungkin berlaku. Oleh itu, Java menyediakan pelbagai mekanisme untuk memastikan penyegerakan benang dan pengecualian bersama akses kepada sumber yang dikongsi.

2.1 kata kunci disegerakkan:
Kata kunci disegerakkan boleh digunakan untuk mengubah suai kaedah atau blok kod untuk menyediakan akses selamat kepada sumber kongsi dalam persekitaran berbilang benang. Apabila benang melaksanakan kaedah disegerakkan atau mengakses blok kod disegerakkan, ia memperoleh kunci objek dan benang lain perlu menunggu kunci dilepaskan.

Berikut ialah contoh mudah:

class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        thread1.start();
        thread2.start();
        
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Count: " + counter.getCount());
    }
}

Dalam contoh di atas, kelas Kaunter ditakrifkan yang mengandungi kaedah untuk menambah kiraan dan mendapatkan kiraan. Kedua-dua kaedah diubah suai dengan kata kunci yang disegerakkan untuk memastikan akses selamat kepada pembolehubah kiraan. Dalam kelas Utama, dua utas dicipta untuk melaksanakan operasi meningkatkan kiraan masing-masing, dan akhirnya mengeluarkan hasil kiraan.

2.2 Antara muka kunci:
Selain kata kunci yang disegerakkan, Java juga menyediakan antara muka Lock dan kelas pelaksanaannya (seperti ReentrantLock) untuk mencapai penyegerakan benang dan pengecualian bersama. Berbanding dengan disegerakkan, antara muka Lock menyediakan kawalan benang yang lebih fleksibel dan boleh mencapai keperluan penyegerakan yang lebih kompleks.

Berikut ialah contoh penggunaan ReentrantLock:

class Counter {
    private int count = 0;
    private Lock lock = new ReentrantLock();
    
    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
    
    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        thread1.start();
        thread2.start();
        
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Count: " + counter.getCount());
    }
}

Dalam contoh di atas, kelas Counter menggunakan ReentrantLock untuk mencapai akses segerak kepada pembolehubah kiraan. Dalam kaedah increment() dan getCount(), dapatkan kunci dengan memanggil kaedah lock() dan kemudian panggil kaedah buka kunci() dalam blok akhirnya untuk melepaskan kunci.

3 Pengurusan sumber dikongsi:
Dalam pengaturcaraan berbilang benang, pengurusan sumber dikongsi adalah kunci untuk memastikan keselamatan benang. Java menyediakan pelbagai mekanisme untuk mengurus sumber yang dikongsi, seperti kata kunci yang tidak menentu, kelas atom, dsb.

3.1 kata kunci meruap: Kata kunci
meruap digunakan untuk mengubah suai pembolehubah yang dikongsi untuk memastikan setiap bacaan atau tulis beroperasi secara langsung pada memori dan bukannya membaca atau menulis daripada cache. Pembolehubah yang diubah suai dengan kata kunci yang tidak menentu kelihatan kepada semua urutan.

Berikut ialah contoh mudah:

class MyThread extends Thread {
    private volatile boolean flag = false;
    
    public void stopThread() {
        flag = true;
    }
    
    @Override
    public void run() {
        while (!flag) {
            // do something
        }
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        thread.stopThread();
        
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Dalam contoh di atas, pembolehubah bendera dalam kelas MyThread diubah suai dengan kata kunci yang tidak menentu untuk memastikan pemberhentian selamat benang. Dalam kelas Utama, cipta objek utas, tunggu satu saat selepas memulakan utas, dan kemudian panggil kaedah stopThread() untuk menghentikan utas.

3.2 Kelas atom:
Java menyediakan satu siri kelas atom (seperti AtomicInteger, AtomicLong), yang boleh memastikan operasi atom selamat benang dan mengelakkan keadaan perlumbaan.

Berikut ialah contoh penggunaan AtomicInteger:

class Counter {
    private AtomicInteger count = new AtomicInteger(0);
    
    public void increment() {
        count.incrementAndGet();
    }
    
    public int getCount() {
        return count.get();
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        thread1.start();
        thread2.start();
        
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Count: " + counter.getCount());
    }
}

Dalam contoh di atas, kelas Counter menggunakan AtomicInteger untuk memastikan pengiraan selamat benang. Dalam kaedah increment(), kiraan dinaikkan secara atom dengan memanggil kaedah incrementAndGet().

Kesimpulan:
Artikel ini meneroka dengan mendalam prinsip-prinsip Java multi-threading daripada mekanisme penjadualan kepada pengurusan sumber yang dikongsi. Memahami prinsip multithreading Java adalah penting untuk menulis program multithreading yang cekap dan boleh dipercayai. Melalui contoh kod di atas, pembaca boleh lebih memahami mekanisme penjadualan dan pengurusan sumber perkongsian Java multi-threading. Pada masa yang sama, pembaca juga boleh memilih mekanisme penyegerakan yang sesuai dan kaedah pengurusan sumber yang dikongsi mengikut keperluan sebenar untuk memastikan ketepatan dan prestasi program berbilang benang.

Atas ialah kandungan terperinci Pemahaman mendalam tentang prinsip berbilang benang Java: daripada mekanisme penjadualan kepada pengurusan sumber yang dikongsi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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