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. 解决ASP.NET中ServiceStack.Redis每小时6000次访问请求的问题

    1.可以使用3.0的版本: Install-Package ServiceStack.Redis -Version 3.0 2.使用ServiceStack.Redis.Complete: Insta ...

  2. java导出csv文件使用Excel打开乱码问题

    写一个csv文件,发现使用 notpad++ 打开是没有问题的,但是使用 Excel 打开之后显示乱码 刚开始的代码是这样子的: ByteArrayOutputStream os = new Byte ...

  3. RPO攻击 & share your mind

    参考文章: https://xz.aliyun.com/t/2220 http://www.thespanner.co.uk/2014/03/21/rpo/ https://www.lorexxar. ...

  4. Matlab 读取 ROS bag 文件指定消息数据

    近期在接触Ros的时候遇到了一些问题,如何将rosbag中的信息提取出来进行进一步处理呢? 如三维点位置信息,视频信息(如果有的话)等等. 我采用的是MATLAB 读取bag信息 filepath=f ...

  5. Android 6.0系统动态请求系统相机权限

    private static final int TAKE_PHOTO_REQUEST_CODE = 1; public static String takePhoto(Context context ...

  6. SpringSecurityOAuth使用JWT Token

    ⒈JWT? JWT(Json Web Token),是Json的一个开放的Token标准. 1,自包含,SpringSecurityOAuth的默认Token是UUID的一个随机的无意义的字符串,并不 ...

  7. CentOS7开启防火墙及特定端口

    开启防火墙服务 以前为了方便,把防火墙都关闭了,因为现在项目都比较重要,害怕受到攻击,所以为了安全性,现在需要将防火墙开启,接下来介绍一下步骤. 1, 首先查看防火墙状态: firewall-cmd ...

  8. Segmentation metrics

    (1)FCN中引入的四种Metrics:

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

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

  10. Linux下编写和加载 .ko 文件(驱动模块文件)

    一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...