Rumah  >  Artikel  >  Java  >  Bagaimanakah Java JUC mengendalikan koleksi kelas keselamatan Senarai?

Bagaimanakah Java JUC mengendalikan koleksi kelas keselamatan Senarai?

WBOY
WBOYke hadapan
2023-04-30 09:10:06737semak imbas

Koleksi tidak selamat

Dalam aplikasi berbenang tunggal, ArrayList() baharu biasanya digunakan untuk menentukan koleksi Senarai untuk menyimpan data boleh berulang.

Walau bagaimanapun, di bawah pelbagai benang, masalah yang tidak dijangka sering berlaku seperti berikut:

import java.util.*;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
        // 创建list集合
        //List<String> lists = Arrays.asList("1", "2", "3");
        // 不安全
        List<String> lists = new ArrayList<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

Apabila berbilang rangkaian beroperasi pada koleksi maklumat objek yang sama, java.util.ConcurrentModificationException selalunya. berlaku maklumat.

Langkah keselamatan disediakan dalam Java

Dalam bahasa java, koleksi Senarai baharu, kelas java.util.Vector, disediakan untuk butiran, lihat kod berikut:

import java.util.*;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
        // 创建list集合
        //List<String> lists = Arrays.asList("1", "2", "3");
        // 不安全
        //List<String> lists = new ArrayList<>();
		List<String> lists = new Vector<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

Tidak akan ada mesej ralat java.util.ConcurrentModificationException.

Mengapa kami boleh memastikan operasi data yang selamat?

Java JUC怎么操作List安全类的集合

menggunakan disegerakkan untuk mengunci pemanggil pelaksanaan kaedah untuk memastikan keselamatan berbilang benang operasi tambah!

Koleksi Senarai Keselamatan di bawah JUC

Di bawah pakej JUC, cara berikut untuk membuat koleksi keselamatan disediakan.

  • Kaedah 1: Collections.synchronizedList(new ArrayList<>());

import java.util.*;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
		List<String> lists = Collections.synchronizedList(new ArrayList<>());

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

Lihat logik pelaksanaan kod sumber yang mendasari

Java JUC怎么操作List安全类的集合

Tentukan jenis koleksi senarai masuk dan tentukan sama ada jenisnya ialah java.util.RandomAccess Jika ya, gunakan java.util.Collections.SynchronizedRandomAccessList untuk membina koleksi. Jika tidak, gunakan java.util.Collections.SynchronizedList membina koleksi.

Logik operasi tambah yang sepadan dalam kod sumber adalah seperti berikut:

Java JUC怎么操作List安全类的集合

Gunakan blok kod penyegerakan yang disegerakkan untuk menambah Operasi data untuk mencapai penguncian!

  • Kaedah 2: new CopyOnWriteArrayList();

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
        List<String> lists = new CopyOnWriteArrayList<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

Pengenalan dalam kod sumber adalah seperti berikut:

Java JUC怎么操作List安全类的集合

Java JUC怎么操作List安全类的集合

Jelas sekali, logiknya adalah seperti berikut:

  1. Selepas memanggil kaedah tambah, dapatkan java.util .concurrent.locks .Maklumat objek ReentrantLock.

  2. Panggil lock.lock() untuk mendapatkan kunci!

  3. Salin objek tatasusunan asal dan buat tatasusunan baharu dengan saiz tatasusunan asal + 1.

  4. Masukkan data baharu ke dalam tatasusunan baharu.

  5. Sebarang operasi akhirnya akan melepaskan kunci!

Dari segi prestasi

Operasi Lock di bawah pakej JUC mempunyai prestasi yang lebih baik daripada yang disegerakkan!

Atas ialah kandungan terperinci Bagaimanakah Java JUC mengendalikan koleksi kelas keselamatan Senarai?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam