Heim häufiges Problem Ist der Hashset-Thread sicher?

Ist der Hashset-Thread sicher?

Apr 25, 2019 pm 01:38 PM
hashset

Was ist Thread-Sicherheit? Das bedeutet, dass das Lesen und Schreiben von Daten threadisoliert sein sollte, was nicht zu Datenverlust oder Inkonsistenz führen sollte. Jedes Mal, wenn die Daten geändert werden, sollten sie nicht überschrieben werden.

Nehmen wir das klassische Beispiel einer Bankabhebung. Konto A liest zunächst 0, Thread A liest 0 und speichert dann 100 (Thread B liest noch 0 und speichert auch 100). Zeit Das letzte Konto, das wir sehen, ist ein Saldo von 100. Dies ist unwissenschaftlich und wird als Thread-unsicher bezeichnet. Daher müssen wir die Objekte für Ein- und Auszahlungen kontrollieren und die von uns betriebenen Objekte sperren lassen. Nach der Aktualisierung der Daten können andere Threads Thread-Sicherheit erreichen.

Ist der Hashset-Thread sicher?

Dieses Mal werden wir HashSet beweisen. Wir wissen, dass die Set-Schnittstelle implementiert ist. Das Merkmal von Set besteht darin, dass die gespeicherten Daten nicht wiederholt werden. Weil es zuerst die intern gespeicherten Daten liest, um zu sehen, ob sie vorhanden sind. Wenn sie vorhanden sind, werden sie nicht darin gespeichert, andernfalls werden sie darin gespeichert. Mit anderen Worten, der Datenspeichervorgang ist in zwei Schritte unterteilt: zuerst das Lesen und dann das Schreiben. Unter der Annahme, dass es nicht threadsicher ist, besteht eine sehr wahrscheinliche Situation darin, dass Thread B, wenn Thread A feststellt, dass das festgelegte Objekt kein Element hat und das Element einfügen möchte, auch feststellt, dass das Objekt nicht über das Element verfügt und dies der Fall ist Ich bereite auch das Einfügen vor. Das Ergebnis ist, dass zwei identische Elemente eingefügt werden.

Wir gestalten die Demo so:

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);
        }
    }
}
Nach dem Login kopieren

Wir testen sie im Hauptthread:

  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());
Nach dem Login kopieren

Die meisten Druckergebnisse liegen bei den erwarteten 5000, aber gelegentlich gibt es solche ein Wert größer als 5000. . Dies führt zu der zuvor erwähnten Situation, die beweist, dass HashSet keine Thread-sichere Klasse ist.

Tatsächlich habe ich beim Betrachten des Quellcodes festgestellt, dass HashMap zur internen Verwaltung von Daten in HashSet verwendet wird. Der Hauptgrund dafür ist, dass HashMap keine Thread-sichere Klasse ist. Dies führt zur Nicht-Thread-Sicherheit von HashSet. Weitere Informationen zu Java-Sammlungsklassen finden Sie unter [Chinesische PHP-Website: Java-Video]

Abschließend noch eine vollständige Code-Fallüberprüfung:

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
    }
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonIst der Hashset-Thread sicher?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Wie verwende ich die Methode HashSet.remove() in Java, um Elemente aus einer Sammlung zu entfernen? Wie verwende ich die Methode HashSet.remove() in Java, um Elemente aus einer Sammlung zu entfernen? Nov 18, 2023 pm 02:17 PM

Verwenden Sie die Methode HashSet.remove() in Java, um bestimmte Elemente aus einer Sammlung zu entfernen. HashSet ist eine Sammlungsklasse, die die Set-Schnittstelle implementiert. Sie erlaubt keine Speicherung doppelter Elemente und garantiert nicht die Reihenfolge der Elemente. Wenn Sie ein HashSet betreiben, können Sie die Methode „remove()“ verwenden, um Elemente im Set zu löschen. Die Methode „remove()“ von HashSet hat zwei überladene Formen: booleanremove(Objectobj): Entfernt das angegebene Objekt aus der Sammlung

So verwenden Sie die HashSet-Funktion für Mengenoperationen in Java So verwenden Sie die HashSet-Funktion für Mengenoperationen in Java Jun 26, 2023 pm 05:15 PM

Die HashSet-Funktion in Java ist eine Sammlungsklasse, die auf Basis einer Hash-Tabelle implementiert wird. Da es sich um eine Sammlungsklasse handelt, hat sie natürlich die Funktion von Sammlungsoperationen. In diesem Artikel wird erläutert, wie die HashSet-Funktion zum Ausführen von Sammlungsoperationen verwendet wird. 1. Definition und Deklaration von HashSet HashSet ist eine Sammlungsklasse, daher müssen Sie zuerst das Java.util-Paket importieren. importjava.util.HashSet; Anschließend können Sie eine HashSet-Instanz erstellen: HashSet&lt;

Interpretation der Java-Dokumentation: Detaillierte Erläuterung der Verwendung der Methode contains() der Klasse HashSet Interpretation der Java-Dokumentation: Detaillierte Erläuterung der Verwendung der Methode contains() der Klasse HashSet Nov 04, 2023 am 11:43 AM

Interpretation der Java-Dokumentation: Detaillierte Erläuterung der Verwendung der Methode contains() der Klasse HashSet. Die Klasse HashSet ist eine der am häufigsten verwendeten Sammlungsklassen in Java. Sie implementiert die Set-Schnittstelle und basiert auf der Hash-Tabellen-Datenstruktur. mit effizienten Einfüge-, Lösch- und Suchvorgängen. Unter diesen ist die Methode contains() eine wichtige Methode der HashSet-Klasse, mit der ermittelt wird, ob die Menge das angegebene Element enthält. In diesem Artikel wird die Verwendung der Methode „contains()“ der Klasse „HashSet“ im Detail analysiert

Fügen Sie alle Elemente einer Sammlung zu einer anderen hinzu, indem Sie die Methode addAll() der Klasse HashSet verwenden Fügen Sie alle Elemente einer Sammlung zu einer anderen hinzu, indem Sie die Methode addAll() der Klasse HashSet verwenden Jul 24, 2023 am 08:58 AM

Verwenden Sie die Methode addAll() der Klasse HashSet, um alle Elemente in einer Sammlung zu einer anderen Sammlung hinzuzufügen. HashSet ist eine Implementierungsklasse im Java-Sammlungsframework. Sie erbt von AbstractSet und implementiert die Set-Schnittstelle. HashSet ist eine ungeordnete Menge, die auf einer Hash-Tabelle basiert und keine doppelten Elemente zulässt. Es bietet viele häufig verwendete Methoden zum Betreiben von Elementen in der Sammlung, darunter die Methode addAll(). Die Funktion der Methode addAll() besteht darin, das angegebene hinzuzufügen

Wie verwende ich die Methode HashSet.add(), um Elemente zu einer Sammlung in Java hinzuzufügen? Wie verwende ich die Methode HashSet.add(), um Elemente zu einer Sammlung in Java hinzuzufügen? Nov 18, 2023 pm 04:56 PM

Es ist sehr einfach, Elemente mit der HashSet.add()-Methode in Java zu einer Sammlung hinzuzufügen. Im Folgenden stellen wir sie ausführlich vor. HashSet ist eine Sammlungsklasse in Java und implementiert die Set-Schnittstelle. HashSet zeichnet sich dadurch aus, dass es ungeordnet ist und sich nicht wiederholt. Die zugrunde liegende Implementierung basiert auf einer Hash-Tabelle. Wenn Sie die Methode HashSet.add () zum Hinzufügen von Elementen verwenden, müssen Sie die folgenden Punkte beachten: HashSet kann nur Elemente vom Objekttyp speichern, nicht

Fügen Sie eine Sammlung zu einer anderen Sammlung hinzu, indem Sie die Methode addAll() der Klasse HashSet verwenden Fügen Sie eine Sammlung zu einer anderen Sammlung hinzu, indem Sie die Methode addAll() der Klasse HashSet verwenden Jul 25, 2023 pm 05:00 PM

Verwenden Sie die Methode addAll() der Klasse HashSet, um einen Satz zu einem anderen Satz hinzuzufügen. HashSet ist eine Sammlungsklasse in Java. Sie implementiert die Set-Schnittstelle und wird basierend auf einer Hash-Tabelle implementiert. Doppelte Elemente sind in der HashSet-Sammlung nicht zulässig und die Elemente in der Sammlung sind ungeordnet. In der Entwicklung müssen wir häufig Elemente aus einer Sammlung zu einer anderen Sammlung hinzufügen. Die HashSet-Klasse stellt die Methode addAll() zur einfachen Implementierung dieser Funktion bereit. Im Folgenden werden wir einen durchgehen

So fügen Sie Traversal-Elemente zu Java HashSet hinzu So fügen Sie Traversal-Elemente zu Java HashSet hinzu Apr 28, 2023 pm 01:04 PM

HashSet-Klassendiagramm HashSet-Kurzbeschreibung 1. HashSet implementiert die Set-Schnittstelle 2. Die unterste Ebene von HashSet wird tatsächlich durch HashMap publicHashSet(){map=newHashMap();} implementiert 3. Null kann gespeichert werden, aber es kann nur eine Null geben 4.HashSet stellt nicht sicher, dass die Elemente in der richtigen Reihenfolge sind (das heißt, es garantiert nicht, dass die Reihenfolge, in der die Elemente gespeichert werden, mit der Reihenfolge übereinstimmt, in der die Elemente herausgenommen werden. Das Ergebnis wird ermittelt). 5. Es können keine doppelten Elemente vorhanden sein. Der zugrunde liegende Mechanismus von HashSet ist HashMap und die unterste Ebene von HashMap ist die Struktur von Array + verknüpfter Liste + Rot-Schwarz-Baum Array + verknüpfte Liste /*

Verwenden Sie die Methode retainAll() der Klasse HashSet, um den Schnittpunkt zweier Mengen zu ermitteln Verwenden Sie die Methode retainAll() der Klasse HashSet, um den Schnittpunkt zweier Mengen zu ermitteln Jul 24, 2023 pm 12:34 PM

Verwenden Sie die Methode retainAll() der Klasse HashSet, um die Schnittmenge zweier Sammlungen zu erhalten. HashSet ist eine Sammlungsklasse in Java, die zum Speichern einer Reihe eindeutiger Objekte verwendet wird. Die Methode retainAll() ist eine von der HashSet-Klasse bereitgestellte Methode, mit der die Schnittmenge zweier HashSets ermittelt wird. In Java ist eine Sammlung eine häufig verwendete Datenstruktur, die zum Speichern mehrerer Objekte verwendet werden kann. HashSet ist eine häufig verwendete konkrete Implementierung in Sammlungsklassen. Es speichert und ruft Objekte über Hash-Tabellen ab.