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 public void clear() {
2 modCount++;
3 Entry[] tab = table;
4 for (int i = 0; i < tab.length; i++)
5 tab[i] = null;
6 size = 0;
7 }
HashMap中的方法containsKey()判断是否含有Key,containsKey()首先通过getEntry()获取key对应的Entry,然后判断Entry是否是NULL
HashMap中的方法containsValue()判断HashMap是否含有值为value 的元素。
HashMap中的方法entrySet()方法的作用是返回一个HashMap中所用的Entry的集合,他是一个集合
HashMap中的方法get()方法获取key对应的value
HashMap中的发方法put()方法作用是提供对外的接口,让HashMap对象可以通过put()将键值对添加到HashMap中
源代码:
 public V put(K key, V value) {
2 // 若“key为null”,则将该键值对添加到table[0]中。
3 if (key == null)
4 return putForNullKey(value);
5 // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
6 int hash = hash(key.hashCode());
7 int i = indexFor(hash, table.length);
8 for (Entry<K,V> e = table[i]; e != null; e = e.next) {
9 Object k;
10 // 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
11 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
12 V oldValue = e.value;
13 e.value = value;
14 e.recordAccess(this);
15 return oldValue;
16 }
17 }
18
19 // 若“该key”对应的键值对不存在,则将“key-value”添加到table中
20 modCount++;
21 addEntry(hash, key, value, i);
22 return null;
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() 方法,则当前线程转入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞状态转为就绪状态。
sleep和yield的区别:
sleep方法是当前线程进入停止状态,所以执行sleep()的线程在指定的时间内不会被执行,yield()只是使得当前线程重新回到可执行状态,所以调用yield()方法的线程可能会进入到执行状态后马上又被执行。 (〃'▽'〃)---- wait()和notify()方法含义:obj.wait()与obj.ootify()必须要与synchronize一起使用,wait和notify是针对已近获取了obj锁进行的操作,从语法角度上说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内
,从功能上说wait就是说线程获取对象锁之后,主动释放对象锁,同时 本线程休眠,直到其他的线程调用对象的notify方法唤醒线程,才能继续获得对象锁,并继续执行。notify()调用后并不是马上释放对象锁,二是在响应的synchronize{}语句块执行完之后,自动释放锁。主要就是wait()方法释放CPU的同时,释放了对象锁的控制。
    如下:是一个使用锁机制结合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();  
                  
              
            } 
 

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. tidb调研

    TiDB是新一代开源分布式 NewSQL 数据库,相比较于我们常见的数据库MySQL,TiDB具有水平伸缩.强一致性的分布式事务.基于 Raft 算法的多副本复制等特性.同时,TiDB兼容MySQL生 ...

  2. java json 转换

    1.直接输出: 2.字符串 通过eval转换输出,里面涉及到一个转义问题,还要注意eval的用法里面需要加"("+ + ")" 3.

  3. Win10提示无法创建新的分区也找不到现有的分区解法

    原文链接:https://www.pconline.com.cn/win10/1126/11261093.html 1.格式化整个硬盘,重新分区 如果你的硬盘上没有重要数据的话,到了分区这一步时,将硬 ...

  4. Linux C++ TCP Socket传输文件或图片实例

    环境:Linux 语言:C++ 通信方式:TCP 下面用TCP协议编写一个简单的服务器.客户端,其中服务器端一直监听本机的6666号端口.如果收到连接请求,将接收请求并接收客户端发来的消息:客户端与服 ...

  5. Django实战(一)-----用户登录与注册系统3(前端页面、登录视图)

    基本框架搭建好了后,我们就要开始丰富页面内容了.最起码,得有一个用户登录的表单不是么?(注册的事情我们先放一边.) 一. 原生HTML页面 删除原来的login.html文件中的内容,写入下面的代码: ...

  6. tomcat quartz 被触发两次

    主要原因为tomcat server.xml 配置问题 <Host appBase="webapps" autoDeploy="true" name=&q ...

  7. 20165231 预习作业3 linux安装及学习

    linux安装 由于以前稍微关注过虚拟机相关知识,所以大致知道虚拟机软件的相关知识.目前我已知的普遍使用的虚拟机软件是VMware Workstation(下文简称VM),VirtualBox(下文简 ...

  8. python二叉树练习

    #coding=utf8 node_list=[5,3,6,2,4,None,8,1,None,None,None,7,9] class Node: def __init__(self,item): ...

  9. latex公式、编号、对齐

    原文地址:http://blog.csdn.net/hjq376247328/article/details/49718931 LaTeX的数学公式有两种,即行中公式和独立公式.行中公式放在正文中间, ...

  10. struts2框架之文件上传(参考第三天学习笔记)

    上传 1. 上传对表单的要求 * method=post * enctype=multipart/form-data 2. 上传对servlet要求 * getParameter()不能再使用! -- ...