1、HashMap概念

HashMap是一个散列表,存储内容是键值对(key-value)的映射,

HashMap继承了AbstractMap,实现了Map、Cloneable、java.io.Serializable的接口

HashMap的实现不是同步的,线程是不安全的,他的Key 、value都可以为null,此外HashMap中的映射不是有序的。

HashMap实例有两个参数影响其性能,分别是 初始容量、加载因子。加载因子就是哈希表在其容量自动创建之前可以达到多满的一种尺度,注意,当哈希表中的条目容量超出当前加载因子和容量的乘积之后,哈希表进行rehash操作,(重建内部的数据结构)

HashMap的构造函数:

// 默认构造函数。
HashMap()

// 指定“容量大小”的构造函数
HashMap(int capacity)

// 指定“容量大小”和“加载因子”的构造函数
HashMap(int capacity, float loadFactor)

// 包含“子Map”的构造函数
HashMap(Map<? extends K, ? extends V> map)

HashMap是通过“拉链法”实现的哈希表,包括几个重要的成员变量,table、size、threshold、loadfactor、modCount、

table是一个Entry[]数组类型,而 entry就是一个单向链表。键值对就存储在Entry数组中。

threshold是HashMap的阈值,用于判断是否需要调整HashMap的容量。

HashMap主要对外接口,clear() 清空整个HashMap 他是将所有的元素设置成NULL实现的。

  1. 1 public void clear() {
  2. 2 modCount++;
  3. 3 Entry[] tab = table;
  4. 4 for (int i = 0; i < tab.length; i++)
  5. 5 tab[i] = null;
  6. 6 size = 0;
  7. 7 }
    HashMap中的方法containsKey()判断是否含有KeycontainsKey()首先通过getEntry()获取key对应的Entry,然后判断Entry是否是NULL
    HashMap中的方法containsValue()判断HashMap是否含有值为value 的元素。
    HashMap中的方法entrySet()方法的作用是返回一个HashMap中所用的Entry的集合,他是一个集合
    HashMap中的方法get()方法获取key对应的value
    HashMap中的发方法put()方法作用是提供对外的接口,让HashMap对象可以通过put()将键值对添加到HashMap
    源代码:
  1. public V put(K key, V value) {
  2. 2 // 若“key为null”,则将该键值对添加到table[0]中。
  3. 3 if (key == null)
  4. 4 return putForNullKey(value);
  5. 5 // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
  6. 6 int hash = hash(key.hashCode());
  7. 7 int i = indexFor(hash, table.length);
  8. 8 for (Entry<K,V> e = table[i]; e != null; e = e.next) {
  9. 9 Object k;
  10. 10 // 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
  11. 11 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
  12. 12 V oldValue = e.value;
  13. 13 e.value = value;
  14. 14 e.recordAccess(this);
  15. 15 return oldValue;
  16. 16 }
  17. 17 }
  18. 18
  19. 19 // 若“该key”对应的键值对不存在,则将“key-value”添加到table中
  20. 20 modCount++;
  21. 21 addEntry(hash, key, value, i);
  22. 22 return null;
  23. 23 }
    HashMap的遍历方式,根据entrySet()获取HashMap的键值对的Set集合,再通过Iterator迭代器遍历得到的集合,
    // 假设map是HashMap对象 // map中的key是String类型,value是Integer类型
    Integer integ = null; Iterator iter = map.entrySet().iterator();
    while(iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); // 获取key key = (String)entry.getKey(); // 获取value integ = (Integer)entry.getValue(); }
    2、线程问题
    (〃'▽'〃)------object类中的wait()方法导致当前的线程等待,直到其他线程调用notify()方法或者notifyAll()唤醒。
    Thread.yield()方法----->线程让步,暂停当前正在执行的线程对象,把机会让给相同或者跟高优先级的线程。
    join()----->线程加入,等待其他线程终止,在当前线程中调用另一个贤臣的join() 方法,则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞状态转为就绪状态。
    sleepyield的区别:
    sleep方法是当前线程进入停止状态,所以执行sleep()的线程在指定的时间内不会被执行,yield()只是使得当前线程重新回到可执行状态,所以调用yield()方法的线程可能会进入到执行状态后马上又被执行。
  24.  
  25. (〃'▽'〃)---- wait()和notify()方法含义:obj.wait()与obj.ootify()必须要与synchronize一起使用,waitnotify是针对已近获取了obj锁进行的操作,从语法角度上说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内
    ,从功能上说wait就是说线程获取对象锁之后,主动释放对象锁,同时 本线程休眠,直到其他的线程调用对象的notify方法唤醒线程,才能继续获得对象锁,并继续执行。notify()调用后并不是马上释放对象锁,二是在响应的synchronize{}语句块执行完之后,自动释放锁。主要就是wait()方法释放CPU的同时,释放了对象锁的控制。
  1. 如下:是一个使用锁机制结合HashMap
    public class CallThread2 {  
     
        static int index = 0;  
        static int max = 4 * 2;  
        static HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();  
        static {  
            for (int i = 0; i < 4; i++) {  
                map.put(i, new ArrayList<Integer>());  
            }  
        }  
        static boolean isRunning = true;  //声明一个标志初始化为真
     
        public static class MyRunnable implements Runnable {  
            int name;  
            Lock lock;  
            Condition condition;  
     
            private MyRunnable(int name, Lock lock, Condition condition) {  
                super();  
                this.name = name;  
                this.lock = lock;  
                this.condition = condition;  
            }  
     
            public boolean isMyName(int index) {  
     
                while (index != name) {  
                    myWait();  
                    if(!isRunning)return false;  
                    return true;  
                      
                }  
                return false;  
            }  
     
            public void myWait() {  
                lock.lock(); //获得锁
                try {  
                    condition.await();  
                } catch (InterruptedException e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
                lock.unlock();  
            }  
     
            public void myNotifyAll() {  
                lock.lock();  
                condition.signalAll();  
                lock.unlock();  
            }  
     
            @Override  
            public void run() {  
                // TODO Auto-generated method stub  
                while (isRunning) {  
                    while (isMyName(index % 4)) {  
              
                    }     
                    if(!isRunning)return;  
                    for (int i = 0, arrIndex = index; i < 4; i++) {  
                        try {  
                            if (arrIndex-- < 0) {  
                                break;  
                            }  
                            List<Integer> list = map.get(i);  
                            if (list.size() < max) {  
                                list.add(name + 1);  
                            }  
                        } catch (Exception e) {  
                        }  
                    }  
     
                    System.err.println("A:" + map.get(0));  
                    System.err.println("B:" + map.get(1));  
                    System.err.println("C:" + map.get(2));  
                    System.err.println("D:" + map.get(3));  
                    System.err.println("-----------------------");  
                    if (map.get(map.size() - 1).size() == max) {              
                        isRunning = false;  
                          
                        myNotifyAll();  
                        return;  
                    } else {  
                        index++;  
                    }     
                    myNotifyAll();  
                      
                  
                } 
  1.  

HashMap&线程的更多相关文章

  1. HashMap的实现原理?如何保证HashMap线程安全?

    A:HashMap简单说就是它根据建的hashcode值存储数据的,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历的顺序是不确定的. B:HashMap基于哈希表,底层结构由数组来实 ...

  2. (转载)两种方法让HashMap线程安全

    HashMap不是线程安全的,往往在写程序时需要通过一些方法来回避.其实JDK原生的提供了2种方法让HashMap支持线程安全. 方法一:通过Collections.synchronizedMap() ...

  3. HashMap线程不安全的体现

    前言:我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线程不安全主要体现在什么地方呢,本文将对该问题进行解密. 1.jdk1.7中的HashMap 在jdk1.8中对HashM ...

  4. 谈谈HashMap线程不安全的体现

    原文出处: Hosee HashMap的原理以及如何实现,之前在JDK7与JDK8中HashMap的实现中已经说明了. 那么,为什么说HashMap是线程不安全的呢?它在多线程环境下,会发生什么情况呢 ...

  5. 为什么HashMap线程不安全,Hashtable和ConcurrentHashMap线程安全

    HashMap源码 public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } final ...

  6. 如何保证HashMap线程安全

    可使用Java 1.5推荐的java.util.concurrent包ConcurrentHashMap来实现,内部不再使用类似HashTable的synchronized同步锁,而是使用Reentr ...

  7. hashmap,hashTable concurrentHashMap 是否为线程安全,区别,如何实现的

    线程安全类 在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的.在jdk1.2之后,就出现许许多多非线程安全的类. 下面是这些线程安全的同步的类: vector:就比arraylist多 ...

  8. 为什么HashMap不是线程安全的

    电面突然被问到这个问题,之前看到过,但是印象不深,导致自己没有答出来,现在总结一下. HashMap的内部存储结构 transient Node<K,V>[] table; static ...

  9. 如何线程安全的使用HashMap

    本文转自:http://www.importnew.com/21396.html 面试时被问到HashMap是否是线程安全的,如何在线程安全的前提下使用HashMap,其实也就是HashMap,Has ...

随机推荐

  1. 【译】第十篇 SQL Server安全行级安全

    本篇文章是SQL Server安全系列的第十篇,详细内容请参考原文. 不像一些其他industrial-strength数据库服务,SQL Server缺乏一个内置保护个别数据记录的机制,称为行级安全 ...

  2. Python 爬虫七 Scrapy

    Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设 ...

  3. 运行APP显示两个APP图标,一个打不开,删除一个后,另一个也会消失。

    可能原因:你添加了两个intent-filter 的LAUNCHER 事件,这种情况尤其在一个项目多个module的时候容易出现 <intent-filter>               ...

  4. SQL攻击-预编译--缓存

    PreparedStatement l 它是Statement接口的子接口: l 强大之处: 防SQL攻击: 提高代码的可读性.可维护性: 提高效率! l 学习PreparedStatement的用法 ...

  5. MyBatis-进阶1

    接入门的实例,我们知道MyBatis可以使用注解和配置文件实现接口和sql语句的绑定. 那么一个接口方法同时使用注解和xml配置会怎么样. @Select("select * from us ...

  6. (转)如何用TensorLayer做目标检测的数据增强

    数据增强在机器学习中的作用不言而喻.和图片分类的数据增强不同,训练目标检测模型的数据增强在对图像做处理时,还需要对图片中每个目标的坐标做相应的处理.此外,位移.裁剪等操作还有可能使得一些目标在处理后只 ...

  7. valgrind简介以及在ARM上交叉编译运行【转】

    转自:https://blog.csdn.net/dengcanjun6/article/details/54958359 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blo ...

  8. 卷积神经网络(matlab实现)

    卷积神经网络是看matlab 的一个toolbox入的门: https://github.com/rasmusbergpalm/DeepLearnToolbox 还有一篇原理推导文献,全是公式: ht ...

  9. Python3学习笔记30-datetime模块

    datetime是Python处理日期和时间的标准库 获取当前的日期和时间 from datetime import datetime now = datetime.now() print(now) ...

  10. HttpResonse 要记得关闭

    写了一个小程序,要识别网站上的图片,用到HttpRequest发请求,HttpResponse接受返回数据.刚开始循环可以跑两个,但是总是提示超时.后来查资料发现,在Http协议中,规定了同个Http ...