자바 JUC 에서 List 보안 클래스 를 조작 하 는 집합 사례

안전 하지 않 은 집합
단일 스 레 드 응용 에 서 는 보통 new Array List()를 사용 하여 반복 가능 한 데 이 터 를 저장 할 수 있 는 List 집합 을 지정 합 니 다.
그러나 다 중 스 레 드 에서 예상 치 못 한 문제 가 발생 할 수 있 습 니 다.코드 는 다음 과 같 습 니 다.

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();
        }
    }
}
그 운행 결 과 는 다음 과 같다.
在这里插入图片描述
다 중 스 레 드 가 같은 집합 대상 정 보 를 조작 하면 자바 util.Concurrent ModificationException 이상 보고 오류 가 발생 합 니 다.
자바 에서 제공 하 는 보안 조치
자바 언어 에 서 는 새로운 List 집합,자바 util.Vector 류 를 제공 합 니 다.다음 코드 를 구체 적 으로 보 세 요.

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();
        }
    }
}
실행 로 그 는 다음 과 같 습 니 다:
在这里插入图片描述
java.util.Concurrent ModificationException 오류 메시지 가 나타 나 지 않 습 니 다.
왜 데이터 의 안전 조작 을 보장 할 수 있 습 니까?
在这里插入图片描述
synchronized 를 사용 하여 호출 자 에 게 자 물 쇠 를 추가 하여 add 작업 의 다 중 스 레 드 안전성 을 확보 합 니 다!
JUC 하의 안전 List 집합
JUC 패키지 아래 다음 과 같은 몇 가지 안전 집합 을 만 드 는 방식 을 제공 합 니 다.
  • 방식 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();
            }
        }
    }
    
    바 텀 소스 코드 를 보고 논 리 를 실현 하 다.
    在这里插入图片描述
    들 어 오 는 list 집합 유형 을 판단 하고 유형 이 java.util.RandomAccess 인지 판단 하 며,그렇다면 java.util.collections.synchronized RandomAccessList 구조 집합 을 사용 하고,그렇지 않 으 면 java.util.collections.synchronized List 구조 집합 을 사용 합 니 다.
    원본 코드 에 대응 하 는 add 작업 논 리 는 다음 과 같 습 니 다.
    在这里插入图片描述
    synchronized 동기 코드 블록 방식 으로 데이터 의 add 작업 에 잠 금 을 추가 합 니 다!
  • 방식 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();
            }
        }
    }
    
    원본 코드 의 소 개 는 다음 과 같다.
    在这里插入图片描述
    在这里插入图片描述
    그 논 리 는 다음 과 같다.
  • add 방법 을 호출 한 후 자바 util.concurrent.locks.ReentrantLock 대상 정 보 를 받 습 니 다.
  • lock.lock()을 호출 하여 자 물 쇠 를 가 져 옵 니 다!
  • 원 배열 대상 copy 를 조작 하고 원 배열 크기+1 의 새 배열 을 만 듭 니 다.
  • 새 데 이 터 를 새 배열 에 넣 습 니 다.
  • 모든 조작 finally,잠 금 해제!
  • 성능 면
    JUC 패키지 의 Lock 작업 은 synchronized 보다 성능 이 좋 습 니 다!
    JUC 에서 List 안전 류 를 조작 하 는 집합 사례 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 JUC 에서 List 안전 류 에 관 한 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기