A hash table supporting full concurrency of retrievals and high expected concurrency for updates. This class obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable. However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access. This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details.
Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset. (More formally, an update operation for a given key bears a happens-before relation with any (non-null) retrieval for that key reporting the updated value.) For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration. They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time. Bear in mind that the results of aggregate status methods including size, isEmpty, and containsValue are typically useful only when a map is not undergoing concurrent updates in other threads. Otherwise the results of these methods reflect transient states that may be adequate for monitoring or estimation purposes, but not for program control.
The table is dynamically expanded when there are too many collisions (i.e., keys that have distinct hash codes but fall into the same slot modulo the table size), with the expected average effect of maintaining roughly two bins per mapping (corresponding to a 0.75 load factor threshold for resizing). There may be much variance around this average as mappings are added and removed, but overall, this maintains a commonly accepted time/space tradeoff for hash tables. However, resizing this or any other kind of hash table may be a relatively slow operation. When possible, it is a good idea to provide a size estimate as an optional initialCapacity constructor argument. An additional optional loadFactor constructor argument provides a further means of customizing initial table capacity by specifying the table density to be used in calculating the amount of space to allocate for the given number of elements. Also, for compatibility with previous versions of this class, constructors may optionally specify an expected concurrencyLevel as an additional hint for internal sizing. Note that using many keys with exactly the same hashCode() is a sure way to slow down performance of any hash table. To ameliorate impact, when keys are Comparable, this class may use comparison order among keys to help break ties.
A Set projection of a ConcurrentHashMap may be created (using newKeySet() or newKeySet(int)), or viewed (using keySet(Object) when only keys are of interest, and the mapped values are (perhaps transiently) not used or all take the same mapping value.
A ConcurrentHashMap can be used as scalable frequency map (a form of histogram or multiset) by using java.util.concurrent.atomic.LongAdder values and initializing via computeIfAbsent. For example, to add a count to a ConcurrentHashMap<String,LongAdder> freqs, you can use freqs.computeIfAbsent(k -> new LongAdder()).increment();
This class and its views and iterators implement all of the optional methods of the Map and Iterator interfaces.
Like Hashtable but unlike HashMap, this class does not allow null to be used as a key or value.
ConcurrentHashMaps support a set of sequential and parallel bulk operations that, unlike most Stream methods, are designed to be safely, and often sensibly, applied even with maps that are being concurrently updated by other threads; for example, when computing a snapshot summary of the values in a shared registry. There are three kinds of operation, each with four forms, accepting functions with Keys, Values, Entries, and (Key, Value) arguments and/or return values. Because the elements of a ConcurrentHashMap are not ordered in any particular way, and may be processed in different orders in different parallel executions, the correctness of supplied functions should not depend on any ordering, or on any other objects or values that may transiently change while computation is in progress; and except for forEach actions, should ideally be side-effect-free. Bulk operations on Map.Entry objects do not support method setValue.
forEach: Perform a given action on each element. A variant form applies a given transformation on each element before performing the action.
search: Return the first available non-null result of applying a given function on each element; skipping further search when a result is found.
reduce: Accumulate each element. The supplied reduction function cannot rely on ordering (more formally, it should be both associative and commutative). There are five variants:
Plain reductions. (There is not a form of this method for (key, value) function arguments since there is no corresponding return type.)
Mapped reductions that accumulate the results of a given function applied to each element.
Reductions to scalar doubles, longs, and ints, using a given basis value.
These bulk operations accept a parallelismThreshold argument. Methods proceed sequentially if the current map size is estimated to be less than the given threshold. Using a value of Long.MAX_VALUE suppresses all parallelism. Using a value of 1 results in maximal parallelism by partitioning into enough subtasks to fully utilize the ForkJoinPool.commonPool() that is used for all parallel computations. Normally, you would initially choose one of these extreme values, and then measure performance of using in-between values that trade off overhead versus throughput.
The concurrency properties of bulk operations follow from those of ConcurrentHashMap: Any non-null result returned from get(key) and related access methods bears a happens-before relation with the associated insertion or update. The result of any bulk operation reflects the composition of these per-element relations (but is not necessarily atomic with respect to the map as a whole unless it is somehow known to be quiescent). Conversely, because keys and values in the map are never null, null serves as a reliable atomic indicator of the current lack of any result. To maintain this property, null serves as an implicit basis for all non-scalar reduction operations. For the double, long, and int versions, the basis should be one that, when combined with any other value, returns that other value (more formally, it should be the identity element for the reduction). Most common reductions have these properties; for example, computing a sum with basis 0 or a minimum with basis MAX_VALUE.
Search and transformation functions provided as arguments should similarly return null to indicate the lack of any result (in which case it is not used). In the case of mapped reductions, this also enables transformations to serve as filters, returning null (or, in the case of primitive specializations, the identity basis) if the element should not be combined. You can create compound transformations and filterings by composing them yourself under this "null means there is nothing there now" rule before using them in search or reduce operations.
Methods accepting and/or returning Entry arguments maintain key-value associations. They may be useful for example when finding the key for the greatest value. Note that "plain" Entry arguments can be supplied using new AbstractMap.SimpleEntry(k,v).
Bulk operations may complete abruptly, throwing an exception encountered in the application of a supplied function. Bear in mind when handling such exceptions that other concurrently executing functions could also have thrown exceptions, or would have done so if the first exception had not occurred.
Speedups for parallel compared to sequential forms are common but not guaranteed. Parallel operations involving brief functions on small maps may execute more slowly than sequential forms if the underlying work to parallelize the computation is more expensive than the computation itself. Similarly, parallelization may not lead to much actual parallelism if all processors are busy performing unrelated tasks.
All arguments to all task methods must be non-null.
This class is a member of the Java Collections Framework.
一種哈希表,支持檢索的完全并發(fā)性和更新的高預(yù)期并發(fā)性。這個(gè)類遵循與Hashtable相同的函數(shù)規(guī)范,并且包含與Hashtable的每個(gè)方法對(duì)應(yīng)的方法版本。但是,即使所有操作都是線程安全的,檢索操作也不需要鎖定,并且不支持以阻止所有訪問的方式鎖定整個(gè)表。此類在依賴于其線程安全性而不依賴于其同步細(xì)節(jié)的程序中與哈希表完全互操作。
檢索操作(包括get)通常不阻塞,因此可能與更新操作(包括put和remove)重疊。檢索反映了最近完成的更新操作在開始時(shí)的結(jié)果。(更正式地說,給定鍵的更新操作與報(bào)告更新值的該鍵的任何(非空)檢索具有“發(fā)生在”關(guān)系。)對(duì)于聚合操作(如putAll和clear),并發(fā)檢索可能只反映插入或刪除某些條目。類似地,迭代器、拆分器和枚舉返回反映哈希表在創(chuàng)建迭代器/枚舉時(shí)或之后某個(gè)點(diǎn)的狀態(tài)的元素。它們不會(huì)拋出ConcurrentModificationException。但是,迭代器設(shè)計(jì)為一次只能由一個(gè)線程使用。請(qǐng)記住,聚合狀態(tài)方法(包括size、isEmpty和containsValue)的結(jié)果通常僅在映射沒有在其他線程中進(jìn)行并發(fā)更新時(shí)才有用。否則,這些方法的結(jié)果反映的瞬態(tài)可能足以用于監(jiān)視或估計(jì)目的,但不足以用于程序控制。
當(dāng)沖突太多時(shí)(即,具有不同哈希碼但落在表大小的同一插槽中的鍵),表將動(dòng)態(tài)展開,預(yù)期的平均效果是每個(gè)映射保持大約兩個(gè)存儲(chǔ)箱(對(duì)應(yīng)于0.75的負(fù)載因子閾值,用于調(diào)整大小)。隨著映射的添加和刪除,這個(gè)平均值可能會(huì)有很大的差異,但總的來說,這為哈希表保持了一個(gè)普遍接受的時(shí)間/空間權(quán)衡。但是,調(diào)整此哈希表或任何其他類型的哈希表的大小可能是一個(gè)相對(duì)緩慢的操作。如果可能,最好提供一個(gè)大小估計(jì)值作為可選的initialCapacity構(gòu)造函數(shù)參數(shù)。另外一個(gè)可選的loadFactor構(gòu)造函數(shù)參數(shù)提供了一種定制初始表容量的方法,它指定了在計(jì)算為給定數(shù)量的元素分配的空間量時(shí)要使用的表密度。此外,為了與此類的早期版本兼容,構(gòu)造函數(shù)可以選擇指定預(yù)期的concurrencyLevel作為內(nèi)部大小調(diào)整的附加提示。請(qǐng)注意,使用具有完全相同hashCode()的多個(gè)鍵肯定會(huì)降低任何哈希表的性能。為了改善影響,當(dāng)鍵具有可比性時(shí),此類可以使用鍵之間的比較順序來幫助打破聯(lián)系。
ConcurrentHashMap的集合投影可以創(chuàng)建(使用newKeySet()或newKeySet(int)),或者查看(使用keySet(Object),當(dāng)只有鍵是感興趣的,并且映射的值(可能是暫時(shí)的)沒有被使用或者全部取相同的映射值時(shí)。
ConcurrentHashMap可以通過使用java.util.concurrent文件.原子長(zhǎng)加法器值并通過ComputeFabSent初始化。例如,要向ConcurrentHashMap<String,LongAdder>freqs添加計(jì)數(shù),可以使用發(fā)送頻率(k->new LongAdder()).increment();
這個(gè)類及其視圖和迭代器實(shí)現(xiàn)了Map和迭代器接口的所有可選方法。
與Hashtable類似,但與HashMap不同,此類不允許將null用作鍵或值。
ConcurrentHashMaps支持一組順序和并行批量操作,與大多數(shù)流方法不同,這些操作被設(shè)計(jì)為安全且通常是合理地應(yīng)用于其他線程同時(shí)更新的映射;例如,在計(jì)算共享注冊(cè)表中值的快照摘要時(shí)。有三種操作,每種都有四種形式,接受帶有鍵、值、條目和(鍵、值)參數(shù)和/或返回值的函數(shù)。因?yàn)镃oncurrentHashMap的元素不是以任何特定的方式排序的,并且可以在不同的并行執(zhí)行中以不同的順序進(jìn)行處理,所以提供的函數(shù)的正確性不應(yīng)該依賴于任何排序,或者依賴于任何其他對(duì)象或值,這些對(duì)象或值在計(jì)算過程中可能會(huì)瞬間改變;并且除了forEach最好是沒有副作用。批量操作地圖輸入對(duì)象不支持方法setValue。
forEach:對(duì)每個(gè)元素執(zhí)行給定的操作。變量形式在執(zhí)行操作之前對(duì)每個(gè)元素應(yīng)用給定的轉(zhuǎn)換。
搜索:返回在每個(gè)元素上應(yīng)用給定函數(shù)的第一個(gè)可用的非空結(jié)果