博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hashtable源码分析
阅读量:6166 次
发布时间:2019-06-21

本文共 3778 字,大约阅读时间需要 12 分钟。

1、Hashtable是线程安全的,采用全量加锁的方式控制多线程并发访问

2、不允许null键和null值(HashMap可以接受为null的键值(key)和值(value))

3、一次仅能有一个对象来读取和修改Hashtable,每个线程要获取或修改都要先拿到同步锁,其他线程要等待同步锁被释放之后才能再次获取同步锁去读取和更新Hashtable

 

构造方法:

// 默认初始容量是11    public Hashtable() {        this(11, 0.75f);    }// 带参构造    public Hashtable(int initialCapacity, float loadFactor) {        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        if (loadFactor <= 0 || Float.isNaN(loadFactor))            throw new IllegalArgumentException("Illegal Load: "+loadFactor);        if (initialCapacity==0)            initialCapacity = 1;        this.loadFactor = loadFactor;      // 初始化哈希表        table = new Entry
[initialCapacity];   // 阀值为初始容量乘负载因子和Integer.MAX_VALUE - 7之间的最小者 threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); }

get方法,put方法,remove方法等对Hashtable进行读取和修改的方法都是同步方法,锁的是Hashtable对象,因此多线程共享一个hashtable对象时,同一时刻只有一个线程能读取和修改Hashtable

@SuppressWarnings("unchecked")    public synchronized V get(Object key) {        Entry
tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry
e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { return (V)e.value; } } return null; } public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry
tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry
entry = (Entry
)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index); return null; }

hashtable put数据时候可以get数据吗?

  多个线程共享一个hashtable对象时,一个get时,另一个不能put。
成员方法中,synchronized锁住的是对象this,只有调用同一个对象的方法才需要获取锁。同时,同一个对象中所有加了synchronize的方法只能一次调 用一个,所以不能。
静态方法中,synchronized锁的是整个类对象,类似于(X.class),该类中所有加了synchronized的静态方法,一次只能调用一个。

验证:

public class HashTable {    private Map
map = new HashMap(); public synchronized String get(String key) { System.out.println("get开始"); String value = map.get(key); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("get结束"); return value; } public synchronized String put(String key, String value) { System.out.println("put开始"); String oldValue = map.put(key, value); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("put结束"); return oldValue; }}public static void main(String[] args) { final HashTable hashTable = new HashTable(); new Thread(new Runnable() {// HashTable hashTable = new HashTable(); @Override public void run() { hashTable.get("name"); } }).start(); new Thread(new Runnable() {// HashTable hashTable = new HashTable(); @Override public void run() { hashTable.put("name", "yangyongjie"); } }).start(); }get开始get结束put开始put结束可以看到不同的同步方法时顺序执行的。

 

转载于:https://www.cnblogs.com/yangyongjie/p/10978833.html

你可能感兴趣的文章
移动端响应式
查看>>
js中var、let、const的区别
查看>>
简洁优雅地实现夜间模式
查看>>
react学习总结
查看>>
在soapui上踩过的坑
查看>>
MySQL的字符集和字符编码笔记
查看>>
ntpd同步时间
查看>>
Maven编译时跳过Test
查看>>
Spring Boot 整合Spring Security 和Swagger2 遇到的问题小结
查看>>
Apache通过mod_php5支持PHP
查看>>
java学习:jdbc连接示例
查看>>
Silverlight 如何手动打包xap
查看>>
HTTP缓存应用
查看>>
KubeEdge向左,K3S向右
查看>>
DTCC2013:基于网络监听数据库安全审计
查看>>
CCNA考试要点大搜集(二)
查看>>
ajax查询数据库时数据无法更新的问题
查看>>
Kickstart 无人职守安装,终于搞定了。
查看>>
linux开源万岁
查看>>
linux/CentOS6忘记root密码解决办法
查看>>