北票网站建设,免费做片头的网站,广州seo公司排名,商旅平台有哪些引子前两天刷抖音#xff0c;看见了这样一个问题。问题#xff1a;容器化不做虚拟内核#xff0c;会有什么弊端#xff1f;Java很多方法会跟CPU的核数有关#xff0c;这个时候调用系统函数#xff0c;读到的是宿主机信息#xff0c;而不是我们限制资源的大小。思考…引子前两天刷抖音看见了这样一个问题。问题容器化不做虚拟内核会有什么弊端Java很多方法会跟CPU的核数有关这个时候调用系统函数读到的是宿主机信息而不是我们限制资源的大小。思考在我们.NET中是否也会出现这种问题呢环境准备1. 准备程序在我们.NET中并行编程Parallel或者线程池ThreedPool中默认会根据CPU数量对我们进行线程分配。于是我就从Parallel中找到TaskReplicator类该类主要用于同时在一个或多个Task中运行委托下的GenerateCooperativeMultitaskingTaskTimeout方法。privatestaticintGenerateCooperativeMultitaskingTaskTimeout()
{// This logic ensures that we have a diversity of timeouts across worker tasks (100, 150, 200, 250, 100, etc)// Otherwise all worker will try to timeout at precisely the same point, which is bad if the work is just about to finish.int period Environment.ProcessorCount;int pseudoRnd Environment.TickCount;return CooperativeMultitaskingTaskTimeout_Min (pseudoRnd % period) * CooperativeMultitaskingTaskTimeout_Increment;
}抽取获取处理器数量方法Environment.ProcessorCount放到控制台中。internalclassProgram
{staticvoidMain(string[] args){Console.WriteLine(获取宿主机器处理器数量Environment.ProcessorCount);Console.ReadLine();}
}2. 环境准备本机CPU--6个虚拟机分配CPU--4个Docker分配CPU--1个测试结果程序最终获取CPU数量是虚拟机的数量采用cpus结果采用–cpuset-cpus命令结果Docker和虚拟机的区别2.分析需求put数据时key值hash后的索引处没有元素需要创建链表头节点放到该位置的数组空间里。key值hash后的索引处有元素说明产生Hash碰撞需要在链表中结尾处挂载节点如果在遍历链表的过程中发现了同key的数据则执行覆盖即可不再继续往下遍历去挂载新节点。假设数组使用的空间超过了总长度的75%那么对数组进行扩容。先创建新数组把旧数据写到新数组中(此时需要重新根据key计算Hash因为数据长度变化了影响计算结果了)在用新数据替换掉原来的旧数组。get数据时key值hash后的索引下标处的元素为空的话则不存在数据。key值hash后的索引下标处存在链表的话需要遍历链表找到key相对应的value值。3.代码实现Node类实现package com.zaevn.hashmap;/*** author: zae* date: 2023/1/30* time: 11:25*/publicclassNode {String key;String value;Node next;publicNode(String key, String value, Node nextNode) {this.key key;this.value value;this.next nextNode;}
}
LinkNode类实现package com.zaevn.hashmap;/*** author: zae* date: 2023/1/30* time: 11:27*/publicclassListNode {// 头节点Node head;/*** 添加数据挂载链表的节点* param key* param value*/publicvoidaddNode(String key,String value){// 如果头节点是空,则结束if(head null ){return;}// 如果头节点不为空则往下挂载节点NodenodenewNode(key,value,null);Nodetemp head;while(true){// 遇到相同的key,覆盖数据if(key.equals(temp.key)){temp.value value;return;}if(temp.next null){break;}temp temp.next;}// 循环结束后则挂上数据temp.next node;}/*** 获取数据* param key* return*/public String getNode(String key){if(head null ){returnnull;}Nodetemp head;while(true){if(key.equals(temp.key)){return temp.value;}if(temp.next null){break;}temp temp.next;}returnnull;}
}
MyHashMap类实现package com.zaevn.hashmap;/*** author: zae* date: 2023/1/30* time: 11:27*/publicclassMyHashMap {// 数组初始化:2的n次方ListNode[] map newListNode[8];// ListNode的个数int size;// 由于扩容时是先创建一个新数组因此先声明出来ListNode[] mapNew;int sizeNew;/*** put方法* param key* param value*/publicvoidput(String key,String value){if(sizemap.length * 0.75){System.out.println(开始进行扩容当前sizesize,数组长度为map.length);doExtendMap();System.out.println(扩容结束当前sizesize,数组长度为map.length);}// 1.对key进行hash算法然后取模intindex Math.abs(key.hashCode())%map.length;ListNodelistNode map[index];// 如果索引位置的元素为空则新加一个元素(创建头节点)if(listNode null){ListNodelistNodeNewnewListNode();NodenodenewNode(key,value,null);listNodeNew.head node;map[index] listNodeNew;size ;}else{// 如果索引位置的元素不为空则往链表中挂载数据listNode.addNode(key,value);}}public String get(String key){// 1.对key进行hash算法然后取模intindex Math.abs(key.hashCode())%map.length;if(map[index] null){returnnull;}else{return map[index].getNode(key);}}/*** 达到阈值后开始进行扩容*/publicvoiddoExtendMap(){sizeNew 0;// 1.先创建一个新的数组长度为原来的二倍mapNew newListNode[map.length * 2];// 2.将旧数据映射到新的数组上(因为数组长度变化因此hash规则变化所有的值需要重新计算hash值)for(inti0;imap.length;i){ListNodelistNode map[i];if(listNode null){continue;}Nodetemp listNode.head;while (true){doPutData(mapNew,temp.key,temp.value);if(temp.next null){break;}temp temp.next;}}// 3.将新的数组替换旧的数组map mapNew;this.size sizeNew;}privatevoiddoPutData(ListNode[] mapParam,String key,String value){intindex Math.abs(key.hashCode())%mapParam.length;ListNodelistNode mapParam[index];if(listNode null){ListNodelistNodeNewnewListNode();NodenodenewNode(key,value,null);listNodeNew.head node;mapParam[index] listNodeNew;sizeNew ;}else{listNode.addNode(key,value);}}publicstaticvoidmain(String[] args) {// 1、一般校验MyHashMap hashMap0newMyHashMap();hashMap0.put(key1,value1);System.out.println(一般校验hashMap0.get(key1));System.out.println(--------------------------------------------);// 2、同key覆盖校验MyHashMap hashMap1newMyHashMap();hashMap1.put(key2,value00);hashMap1.put(key2,value01);System.out.println(同key覆盖校验hashMap1.get(key2));System.out.println(--------------------------------------------);// 3、哈希碰撞校验(k1和k9的经过哈希计算后得到的索引都是6)MyHashMap hashMap2newMyHashMap();hashMap2.put(k1,value_k1);hashMap2.put(k9,value_k9);System.out.println(哈希碰撞校验k1:hashMap2.get(k1) k9:hashMap2.get(k9));System.out.println(--------------------------------------------);// 4、扩容校验MyHashMap hashMap3newMyHashMap();hashMap3.put(m3,cccccc);hashMap3.put(c1,kkkkkk);hashMap3.put(c2,mmmmmmm);hashMap3.put(b1,bbbbbbb);hashMap3.put(m1,cccccc);hashMap3.put(c3,kkkkkk);hashMap3.put(c4,mmmmmmm);hashMap3.put(b2,bbbbbbb);hashMap3.put(m2,cccccc);hashMap3.put(c5,kkkkkk);hashMap3.put(c6,mmmmmmm);hashMap3.put(b3,bbbbbbb);System.out.println(扩容后的c4:hashMap3.get(c4));System.out.println(扩容后的b3:hashMap3.get(b3));}}
3.运行结果