일반적인 문제 해시셋 스레드는 안전한가요?

해시셋 스레드는 안전한가요?

Apr 25, 2019 pm 01:38 PM
hashset

스레드 안전성이란 무엇입니까? 데이터 읽기 및 쓰기가 스레드 격리되어야 하며 데이터가 수정될 때마다 덮어쓰면 안 됩니다.

계좌 A는 처음에 0을 읽고 스레드 A는 0을 읽은 다음 100을 저장합니다(아직 데이터가 기록되지 않음). 스레드 B도 0을 읽고 100을 저장합니다. 이때 우리가 보는 최종 계좌의 잔액은 100이다. 이는 비과학적이며 스레드 안전하지 않다고 합니다. 따라서 우리는 입출금을 위한 개체를 제어해야 하며, 데이터를 업데이트한 후 다른 스레드가 스레드 안전을 달성할 수 있도록 우리가 운영하는 개체를 허용해야 합니다.

해시셋 스레드는 안전한가요?

이번에는 HashSet을 증명하겠습니다. Set 인터페이스가 구현되어 있다는 것을 알고 있습니다. Set의 특징은 저장된 데이터가 반복되지 않는다는 것입니다. 먼저 내부에 저장된 데이터를 읽어서 존재 여부를 확인하기 때문에 존재하는 경우에는 저장되지 않고 그렇지 않은 경우에는 저장됩니다. 즉, 데이터 저장 작업은 먼저 읽기와 쓰기의 두 단계로 나누어집니다. 스레드로부터 안전하지 않다고 가정하면 스레드 A가 집합 개체에 요소가 없고 요소를 삽입하려고 한다고 판단할 때 스레드 B도 개체에 요소가 없다고 판단하여 요소를 삽입할 가능성이 매우 높습니다. 마지막으로 두 개의 동일한 요소가 삽입됩니다.

데모를 다음과 같이 디자인합니다:

class TestHashSet implements Runnable{
    // 实现Runnable 让该集合能被多个线程访问
    Set<Integer> set = new HashSet<Integer>();
    // 线程的执行就是插入5000个整数
    @Override
    public void run() {
        for (int i = 0;i < 5000;i ++) {
            set.add(i);
        }
    }
}
로그인 후 복사

메인 스레드에서 테스트합니다:

  TestHashSet run2 = new TestHashSet();
        // 实例化两个线程
        Thread t6 = new Thread(run2);
        Thread t7 = new Thread(run2);
        // 启动两个线程
        t6.start();
        t7.start();
        // 当前线程等待加入到调用线程后
        t6.join();
        t7.join();
        // 打印出集合的size
        System.out.println(run2.set.size());
로그인 후 복사

대부분의 인쇄 결과는 예상되는 5000입니다. , 그러나 때때로 5000보다 큰 상황이 있을 수 있습니다. 이는 앞서 언급한 상황으로 이어지며, 이는 HashSet이 스레드로부터 안전한 클래스가 아님을 증명합니다.

사실 소스 코드를 보면 HashSet이 HashMap을 사용하여 내부적으로 데이터를 유지 관리하는 것으로 나타났습니다. 근본적인 이유는 HashMap이 스레드로부터 안전한 클래스가 아니라는 것입니다. 이는 HashSet의 스레드가 아닌 안전성으로 이어집니다. Java 컬렉션 클래스에 대한 자세한 내용은 [PHP 중국어 웹사이트: javavideo]

마지막으로 전체 코드 케이스 확인을 살펴보겠습니다.
# 🎜🎜#

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 验证HashSet不是线程安全
 */
public class HashSetTest {
    public static void main(String[] args) {
        final Set<Integer> set = new HashSet<>();// 结果可能大于1000
//        final Set<Integer> set = Collections.synchronizedSet(new HashSet<>());// 结果等于1000
//        final Set<Integer> set = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());// 结果等于1000
        // 往set写入1-1000
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 1000; i++) {
                    set.add(i);
                }
            }
        };
        int threadNum = 10;// 线程数
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < threadNum; i++) {
            Thread thread = new Thread(runnable);
            threadList.add(thread);
            thread.start();
        }
        // 主线程等待子线程执行完成
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(set.size());// 结果可能大于1000
    }
}
로그인 후 복사

위 내용은 해시셋 스레드는 안전한가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

컬렉션에서 요소를 제거하기 위해 Java에서 HashSet.remove() 메서드를 사용하는 방법은 무엇입니까? 컬렉션에서 요소를 제거하기 위해 Java에서 HashSet.remove() 메서드를 사용하는 방법은 무엇입니까? Nov 18, 2023 pm 02:17 PM

컬렉션에서 지정된 요소를 제거하려면 Java에서 HashSet.remove() 메서드를 사용합니다. HashSet은 Set 인터페이스를 구현하는 컬렉션 클래스입니다. 이는 중복된 요소의 저장을 허용하지 않으며 요소의 순서를 보장하지 않습니다. HashSet을 작동할 때 Remove() 메소드를 사용하여 세트의 요소를 삭제할 수 있습니다. HashSet의 Remove() 메서드에는 두 가지 오버로드된 형식이 있습니다. booleanremove(Objectobj): 컬렉션에서 지정된 개체를 제거합니다.

Java에서 집합 작업에 HashSet 함수를 사용하는 방법 Java에서 집합 작업에 HashSet 함수를 사용하는 방법 Jun 26, 2023 pm 05:15 PM

Java의 HashSet 함수는 해시 테이블을 기반으로 구현된 컬렉션 클래스입니다. 컬렉션 클래스이기 때문에 자연스럽게 컬렉션 연산의 기능을 가지고 있습니다. 이번 글에서는 HashSet 함수를 사용하여 컬렉션 연산을 수행하는 방법을 소개하겠습니다. 1. HashSet 정의 및 선언 HashSet은 컬렉션 클래스이므로 먼저 Java.util 패키지를 가져와야 합니다. importjava.util.HashSet; 그런 다음 HashSet 인스턴스를 생성할 수 있습니다. HashSet&lt;

Java 문서 해석: HashSet 클래스의 contain() 메소드 사용법에 대한 자세한 설명 Java 문서 해석: HashSet 클래스의 contain() 메소드 사용법에 대한 자세한 설명 Nov 04, 2023 am 11:43 AM

Java 문서 해석: HashSet 클래스의 contain() 메소드 사용법에 대한 자세한 설명 HashSet 클래스는 Java에서 일반적으로 사용되는 컬렉션 클래스 중 하나이며 해시 테이블 데이터 구조를 기반으로 합니다. 효율적인 삽입, 삭제, 검색 작업을 통해 그 중 Contains() 메소드는 HashSet 클래스에서 제공하는 중요한 메소드로 세트에 지정된 요소가 포함되어 있는지 확인하는 데 사용됩니다. 이 글에서는 HashSet 클래스의 Contains() 메소드 사용법을 자세히 분석하고,

HashSet 클래스의 addAll() 메서드를 사용하여 한 컬렉션의 모든 요소를 ​​다른 컬렉션에 추가합니다. HashSet 클래스의 addAll() 메서드를 사용하여 한 컬렉션의 모든 요소를 ​​다른 컬렉션에 추가합니다. Jul 24, 2023 am 08:58 AM

HashSet 클래스의 addAll() 메소드를 사용하여 컬렉션의 모든 요소를 ​​다른 컬렉션에 추가합니다. HashSet은 Java 컬렉션 프레임워크의 구현 클래스이며 Set 인터페이스를 구현합니다. HashSet은 해시 테이블을 기반으로 하는 순서가 지정되지 않은 집합으로 중복 요소를 허용하지 않습니다. 이는 컬렉션의 요소를 조작하기 위해 일반적으로 사용되는 여러 가지 메소드를 제공하며, 그 중 하나가 addAll() 메소드입니다. addAll() 메소드의 기능은 지정된 항목을 추가하는 것입니다.

HashSet.add() 메서드를 사용하여 Java 컬렉션에 요소를 추가하는 방법은 무엇입니까? HashSet.add() 메서드를 사용하여 Java 컬렉션에 요소를 추가하는 방법은 무엇입니까? Nov 18, 2023 pm 04:56 PM

Java에서 HashSet.add() 메소드를 사용하여 컬렉션에 요소를 추가하는 것은 매우 간단합니다. 아래에서 자세히 소개하겠습니다. HashSet은 Java의 컬렉션 클래스입니다. AbstractSet 클래스를 상속하고 Set 인터페이스를 구현합니다. HashSet은 순서가 없고 반복되지 않는 특징이 있으며 기본 구현은 해시 테이블을 기반으로 합니다. HashSet.add() 메서드를 사용하여 요소를 추가할 때 다음 사항에 주의해야 합니다. HashSet은 개체 유형의 요소만 저장할 수 있으며, 요소를 저장할 수는 없습니다.

HashSet 클래스의 addAll() 메서드를 사용하여 다른 컬렉션에 컬렉션 추가 HashSet 클래스의 addAll() 메서드를 사용하여 다른 컬렉션에 컬렉션 추가 Jul 25, 2023 pm 05:00 PM

HashSet 클래스의 addAll() 메소드를 사용하여 세트를 다른 세트에 추가하십시오. HashSet은 Java의 컬렉션 클래스이며 해시 테이블을 기반으로 구현됩니다. HashSet 컬렉션에서는 중복된 요소가 허용되지 않으며 컬렉션의 요소는 순서가 지정되지 않습니다. 개발 중에는 한 컬렉션의 요소를 다른 컬렉션에 추가해야 하는 경우가 많습니다. HashSet 클래스는 이 기능을 쉽게 구현할 수 있도록 addAll() 메서드를 제공합니다. 아래에서 우리는

Java HashSet에 순회 요소를 추가하는 방법 Java HashSet에 순회 요소를 추가하는 방법 Apr 28, 2023 pm 01:04 PM

HashSet 클래스 다이어그램 HashSet 간략한 설명 1. HashSet은 Set 인터페이스를 구현합니다. 2. HashSet의 하위 계층은 실제로 HashMap publicHashSet(){map=newHashMap();}에 의해 구현됩니다. 3. Null을 저장할 수 있지만 null은 하나만 있을 수 있습니다. 4.HashSet은 요소의 순서가 올바른지 확인하지 않습니다(즉, 요소가 저장된 순서와 요소를 꺼내는 순서가 일치함을 보장하지 않습니다). 5. HashSet의 기본 메커니즘은 HashSet의 하위 레이어가 HashMap이고 HashMap의 하위 레이어가 배열 + 연결 목록 + 레드-블랙 트리 시뮬레이션이라고 설명합니다. 배열 + 연결리스트 /*

두 집합의 교집합을 얻으려면 HashSet 클래스의 keepAll() 메서드를 사용하세요. 두 집합의 교집합을 얻으려면 HashSet 클래스의 keepAll() 메서드를 사용하세요. Jul 24, 2023 pm 12:34 PM

두 컬렉션의 교차점을 얻으려면 HashSet 클래스의 keepAll() 메서드를 사용하십시오. HashSet은 고유한 개체 집합을 저장하는 데 사용되는 Java의 컬렉션 클래스입니다. keepAll() 메소드는 HashSet 클래스에서 제공하는 메소드로 두 HashSet의 교집합을 구하는 데 사용됩니다. Java에서 컬렉션은 여러 개체를 저장하는 데 사용할 수 있는 일반적으로 사용되는 데이터 구조입니다. HashSet은 컬렉션 클래스에서 일반적으로 사용되는 구체적인 구현입니다. 해시 테이블을 통해 개체를 저장하고 검색합니다.