一、阻塞队列
对于许多线程问题,可以通过使用一个或多个队列以优雅且安全的方式将其形式化。当试图向队列添加元素而队列已满,或是想从队列移除元素而队列为空的时候,阻塞队列导致线程阻塞。
1、阻塞队列方法分为以下3类:
如果将队列当作线程管理工具来使用,将要用到put和take方法;
当试图向满的队列中添加元素或是从空的队列中移除元素时,add、remove和element操作抛出异常;
在一个多线程程序中,队列会在任何时候空或满,因此,一定要使用offer、poll和peek方法作为代替;
2、offer方法和poll方法带有超时的方法变体
boolean success = q.offer(x, 100, TimeUnit.MILLISECONDS);
3、Java.util.concurrent包提供了阻塞队列的几种变种:
LinkedBlockingQueue:容量没有上限,但也可以指定最大容量;
ArrayBlockingQueue:在构造时需要指定容量,并且可以设置公平参数,但会降低性能;
PriorityBlockingQueue:带优先级的队列,不是先进先出,按照它们的优先级顺序移出;
DelayQueue:支持延迟获取元素,内部采用优先队列,同时元素必须实现Delayed接口;
LinkedTransferQueue:允许生产者线程等待,直到消费者准备就绪可以接收一个元素;
二、线程安全的集合(java.util.concurrent)(一)
1、高效的映射、集和队列
ConcurrentLinkedQueue():线程安全无边界非阻塞的队列;
ConcurrentSkipListSet():线程安全的有序集;
ConcurrentHashMap(int initialCapacity, float loadFactor, int concurrencyLevel):线程安全访问的散列映射表 initialCapacity:初始容量 loadFactor:桶的控制调整因子 concurrencyLevel:线程估计数;
ConcurrentSkipListSet:线程安全的有序的映像表;
2、映射条目的原子更新
如果多个线程修改一个普通的HashMap,他们会破坏内部结构(一个链表数组)。例如,有些链接可能丢失,或者甚至会构成循环,使这个数据结构不再可用。对于线程安全的集合来说,是绝对不会发生这种情况的。但是由于操作并非是原子性的(即对变量的基本数据类型的赋值),这种情况的结果是不可预知的。
传统的做法是使用replace操作,它会用原子的方式用一个新值替换原值。必须使用while循环,确保replace的时候没有其他线程把原值替换为其他值。
在Java8中,可以使用ConcurrentHashMap<String,AtomicLong>或者ConcurrentHashMap<String,LongAdder>来实现原子自增。
注:longAdder.increment()方法可以完成本次数据的增加;
除此之外,map的merge和compute方法也是支持原子操作的。例如,map.compute(word,(k,v)-> v == null?1:V+1)或者map.merge(word, 1l, Long::sum);
注:merge方法中,如果key存在,则执行lambda表达式,如果key不存在,则直接put第二个参数值
三、IP基本认识
IP在TCP/IP参考模型处于第三层,也就是网络层。网络层的主要作用是实现主机与主机之后的通信,也就是点对点通信。源IP地址和目标IP地址在传输过程中是不会变化的,只有源MAC地址和目标MAC地址一直在变化;
1、一块网卡也可以设置两个以上的IP;
2、IP地址的分类
IP地址是由网络号+主机号组成的;主机号全为1指定某个网络下的所有主机,用于广播;主机号全部为0 的网络号指向那个网段,即该IP代表一个网段;这两个IP均不能分配给主机;
3、广播地址的作用
同一个链路中相互连接的主机之间发送数据包。
本地广播
在本网络内广播称为本地广播,这个广播地址的IP包会被路由器屏蔽,不会到达其他链路上。
直接广播
不同网段之间的广播。例如在192.168.0.0/24的主机向192.168.1.255/24的目标地址发送IP包。收到这个包的路由器,将数据转发到192.168.1.0/24网段,从而使这个网段内的主机都能收到这个包。由于直接广播存在安全问题,多数情况下,路由器被设置为不转发。
4、D、E类地址
这两类地址没有主机号,不可用于主机IP。D类多用于多播,E类是预留的分类,暂时没有使用。
多播与广播不同,是用于发送给特定组内的所有主机。
5、IP分类的缺点以及解决方案
a.缺点
同一网络下没有地址层次。同一类地址下面,不能根据现场环境的分类在划分地址层次;
分类的个数不能与现实网络情况匹配;
b.无分类地址CIDR(不具有分类地址的概念)
表现形式a.b.c.d/X表示前X位属于网络号,x的范围是0~32。
c.子网掩码(掩盖掉主机号,剩下网络号)
将子网掩码与IP地址按位计算AND,就可以得到网络号;
6、如何进行子网划分(子网掩码)
子网划分实际上是将主机地址分为两个部分:子网网络地址和子网主机地址
可以根据子网掩码的对应区域的位数来判断划分了几个子网。例如,对于C类IP,对于子网掩码255.255.255.192(192=128+64)可以划分以下的子网:
7、公有IP与私有IP
8、IP地址与路由控制
IP地址的网络地址这一部分是用于进行路由控制。
路由控制表中记录着网络地址与下一步应该发送至路由器的地址。
在发送IP包时,首先要确定IP包首部中的目标地址,在从路由控制表中找到与该地址具有相同网络地址的记录,根据该记录将IP包转发给相应的下一个路由器。如果路由控制表中存在多条相同网络地址的记录,就选择相同位数最多的网络地址,也就是最长匹配。
9、IP分片与重组
MTU的定义就是数据链路层允许的最大IP包长。对于以太网来说,它的MTU是1500字节。当IP数据包大小大于MTU时,IP数据包就会被分片。经过分片之后的IP数据报在被重组的时候,只能由目标主机进行,路由器是不会进行重组的。