Pod初始化容器之Init Container

Init 容器的介绍

Pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init容器
Init 容器与普通的容器非常像,除了如下两点:
  c Init 容器总是运行到成功完成为止
  2) 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成
如果 Pod 的 Init 容器失败, Kubernetes 会不断地重启该 Pod ,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 为 Never。
Init 容器的作用

因为 Init 容器具有与应用程序容器分离的单独镜像,所以它们的启动相关代码具有如下优势:
1)它们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的
2)  它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要 FROM 另一个镜像,只需要在安装过程中使用类似 sed 、 awk 、 python 或 dig
这样的工具。
3)  应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
4)  Init 容器使用 Linux Namespace ,所以相对应用程序容器来说具有不同的文件系统视图。因此,它们能够具有访问 Secret 的权限,而应用程序容器则不能。
5) 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以 Init 容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。

 测试

说明:主要是在启动Pod,有2个initc,一开始是没有准备的,所以现象会显示初始化0/2

init.yaml

kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: [‘sh‘, ‘-c‘, ‘echo The app is running! && sleep 3600‘]
  initContainers:
  - name: init-myservice
    image: busybox
    command: [‘sh‘, ‘-c‘, ‘until nslookup myservice; do echo waiting for myservice; sleep 2; done;‘]
  - name: init-mydb
    image: busybox
    command: [‘sh‘, ‘-c‘, ‘until nslookup mydb; do echo waiting for mydb; sleep 2; done;‘]
[[email protected] mnt]# kubectl create -f init.yaml
pod/myapp-pod created
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          8s
[root@k8s-master mnt]# kubectl describe myapp-pod
error: the server doesn‘t have a resource type "myapp-pod"
[root@k8s-master mnt]# kubectl describe pod myapp-pod
Name:         myapp-pod
Namespace:    default
Priority:     0
Node:         k8s-node02/192.168.180.134
Start Time:   Wed, 18 Dec 2019 22:02:57 +0800
Labels:       app=myapp
Annotations:  <none>
Status:       Pending
IP:           10.244.1.9
IPs:
  IP:  10.244.1.9
Init Containers:
  init-myservice:
    Container ID:  docker://3c0e850042efab506f95737adfd3dc6ef2da9218ce51eb5eb4e94573a657fd2b
    Image:         busybox
    Image ID:      docker-pullable://[email protected]sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      until nslookup myservice; do echo waiting for myservice; sleep 2; done;
    State:          Running
      Started:      Wed, 18 Dec 2019 22:03:03 +0800
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-gx2h8 (ro)
  init-mydb:
    Container ID:
    Image:         busybox
    Image ID:
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      until nslookup mydb; do echo waiting for mydb; sleep 2; done;
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-gx2h8 (ro)
Containers:
  myapp-container:
    Container ID:
    Image:         busybox
    Image ID:
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      echo The app is running! && sleep 3600
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-gx2h8 (ro)
Conditions:
  Type              Status
  Initialized       False
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-gx2h8:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-gx2h8
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From                 Message
  ----    ------     ----       ----                 -------
  Normal  Scheduled  <unknown>  default-scheduler    Successfully assigned default/myapp-pod to k8s-node02
  Normal  Pulling    22s        kubelet, k8s-node02  Pulling image "busybox"
  Normal  Pulled     18s        kubelet, k8s-node02  Successfully pulled image "busybox"
  Normal  Created    18s        kubelet, k8s-node02  Created container init-myservice
  Normal  Started    17s        kubelet, k8s-node02  Started container init-myservice

查看myservice

[[email protected] mnt]# kubectl logs myapp-pod -c init-myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice
Server:         10.96.0.10
Address:        10.96.0.10:53

** server can‘t find myservice.default.svc.cluster.local: NXDOMAIN

*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer
*** Can‘t find myservice.default.svc.cluster.local: No answer
*** Can‘t find myservice.svc.cluster.local: No answer
*** Can‘t find myservice.cluster.local: No answer
*** Can‘t find myservice.localdomain: No answer

waiting for myservice

myservice.yaml

[[email protected] mnt]# cat myservice.yaml
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
[root@k8s-master mnt]#
[[email protected] mnt]# vim myservice.yaml
[[email protected] mnt]# kubectl create -f myservice.yaml
service/myservice created
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          4m23s
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          4m25s
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          4m27s
[root@k8s-master mnt]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   10h
myservice    ClusterIP   10.102.35.5   <none>        80/TCP    49s
[root@k8s-master mnt]# kubectl get pod -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-58cc8c89f4-pzbrd             1/1     Running   23         10h
coredns-58cc8c89f4-vmhl2             1/1     Running   23         10h
etcd-k8s-master                      1/1     Running   4          10h
kube-apiserver-k8s-master            1/1     Running   4          10h
kube-controller-manager-k8s-master   1/1     Running   21         10h
kube-flannel-ds-amd64-c4fs4          1/1     Running   2          9h
kube-flannel-ds-amd64-ct6mc          1/1     Running   2          9h
kube-flannel-ds-amd64-mtzz9          1/1     Running   5          9h
kube-proxy-9bdql                     1/1     Running   2          9h
kube-proxy-cv8lk                     1/1     Running   2          9h
kube-proxy-h8jk8                     1/1     Running   4          10h
kube-scheduler-k8s-master            1/1     Running   21         10h
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:1/2   0          5m58s
[root@k8s-master mnt]# vim myservice.yaml
[[email protected] mnt]# kubectl create -f myservice.yaml
service/myservice created
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          4m23s
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          4m25s
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:0/2   0          4m27s
[root@k8s-master mnt]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   10h
myservice    ClusterIP   10.102.35.5   <none>        80/TCP    49s
[root@k8s-master mnt]# kubectl get pod -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-58cc8c89f4-pzbrd             1/1     Running   23         10h
coredns-58cc8c89f4-vmhl2             1/1     Running   23         10h
etcd-k8s-master                      1/1     Running   4          10h
kube-apiserver-k8s-master            1/1     Running   4          10h
kube-controller-manager-k8s-master   1/1     Running   21         10h
kube-flannel-ds-amd64-c4fs4          1/1     Running   2          9h
kube-flannel-ds-amd64-ct6mc          1/1     Running   2          9h
kube-flannel-ds-amd64-mtzz9          1/1     Running   5          9h
kube-proxy-9bdql                     1/1     Running   2          9h
kube-proxy-cv8lk                     1/1     Running   2          9h
kube-proxy-h8jk8                     1/1     Running   4          10h
kube-scheduler-k8s-master            1/1     Running   21         10h
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:1/2   0          5m58s

现象:发现变成1/2了

[[email protected] mnt]# cat mydb.yaml
kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377
[root@k8s-master mnt]#
[[email protected] mnt]# vim mydb.yaml
[[email protected] mnt]# kubectl create -f mydb.yaml
service/mydb created
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:1/2   0          11m
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS     RESTARTS   AGE
myapp-pod   0/1     Init:1/2   0          11m
[root@k8s-master mnt]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
myapp-pod   1/1     Running   0          12m
[root@k8s-master mnt]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   10h
mydb         ClusterIP   10.104.158.92   <none>        80/TCP    3m24s
myservice    ClusterIP   10.102.35.5     <none>        80/TCP    10m
[root@k8s-master mnt]#

现象:myapp-pod起来了

说明

  • 在 Pod 启动过程中, Init 容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出
  • 如果由于运行时或失败退出,将导致容器启动失败,它会根据 Pod 的 restartPolicy 指定的策略进行重试。然而,如果 Pod 的 restartPolicy 设置为 Always , Init 容器失败时会使用RestartPolicy 策略
  • 在所有的 Init 容器没有成功之前, Pod 将不会变成 Ready 状态。 Init 容器的端口将不会在Service 中进行聚集。 正在初始化中的 Pod 处于 Pending 状态,但应该会将 Initializing 状态设置为 true
  • 如果   Pod  重启,所有 Init 容器必须重新执行
  • 对 Init 容器 spec 的修改被限制在容器 image 字段,修改其他字段都不会生效。更改 Init容器的 image 字段,等价于重启该 Pod
  • Init 容器具有应用容器的所有字段。除了 readinessProbe ,因为 Init 容器无法定义不同于完成( completion )的就绪( readiness )之外的其他状态。这会在验证过程中强制
  • 在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误

原文地址:https://www.cnblogs.com/dalianpai/p/12064459.html

时间: 2024-08-28 22:53:16

Pod初始化容器之Init Container的相关文章

A022-列表容器之ExpandableListView

概述 本节课介绍Android中可实现二级可展开收缩列表的ExpandableListView容器,笔者感觉它非常难用并且难理解,很多时候我们可能需要对控件进行扩展和定制,然而它不太方便扩展,它使用难点主要在数据结构上和对控件的事件监听,其他的实现方式类似ListView,下面会提供笔者在实际开发中使用到的案例. 案例 上面实现的效果可展开的二级列表,每个组项都可能有若干个子项,默认的ExpandableListView不太美观,我们需要通过自定义布局类美化它,在使用过程中有一些需要我们去了解的

初探STL容器之Vector

vector 特点: 1.可变长的动态数组 2.使用时包含头文件 #include <vector> 3.支持随机访问迭代器 ? 根据下标随机访问某个元素时间为常数 ? 在尾部添加速度很快 ? 在中间插入慢 成员函数 初始化 vector(); 初始化成空 vector(int n); 初始化成有n个元素 vector(int n, const T & val); 初始化成有n个元素, 每个元素的值都是val,类型是T vector(iterator first, iterator l

初探STL容器之List

List 特点: 1.实质上是双向链表 2.使用时包含<list>头文件 #include<list> 3.不支持随机访问迭代器,只能使用双向迭代器  //因此不能使用一些算法和运算符操作 4.在任何位置的插入.删除操作都是常数时间 成员函数 初始化 list <int> intlist0; // 创建空的 intlist list <int> intlist1( 3 ); //包含3个元素 list <int> intlist2( 5, 2 )

STL源码笔记(12)—序列式容器之deque(二)

STL源码笔记(12)-序列式容器之deque(二) 再谈deque数据结构 我们知道deque是通过map管理很多个互相独立连续空间,由于对deque_iterator的特殊设计,使得在使用的时候就好像连续一样.有了deque_iterator的基础(例如重载的操作符等),对于我们实现容器的一些方法就十分方便了.与vector一样,deque也维护一个start,和finish两个迭代器,start指向容器中的一个元素,finish指向最后一个元素的后一个位置(前闭后开),从微观上讲,star

Java并发编程:并发容器之ConcurrentHashMap(转)

本文转自:http://www.cnblogs.com/dolphin0520/p/3932905.html Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都 串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了并发性,当多个线程

Java并发编程:并发容器之CopyOnWriteArrayList(转)

本文转自:http://www.cnblogs.com/dolphin0520/p/3938914.html Java并发编程:并发容器之CopyOnWriteArrayList(转载) 原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略.从J

STL学习笔记--4、序列式容器之vector

常见的数据结构:array数组,list链表,tree树,stack栈,queue队列,hash table散列表,set集合,map映射-- 根据数据在容器中的排列分为:序列式sequence和关联式associative. 序列式容器之vector 1.vector VS array: array是静态空间,一旦配置则无法改变: vector是动态空间,随着元素的加入,内部机制会自动扩充新的空间来容纳新的元素. 实现技术:对大小的控制和重新配置时的数据移动效率. 扩充空间:配置新空间.数据移

并发容器之ConcurrentHashMap(转载)

Java并发编程:并发容器之ConcurrentHashMap(转载) 下面这部分内容转载自: http://www.haogongju.net/art/2350374 JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都 串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了并发性,当多个线程竞争容器时,吞吐量严重降低.因此Java5.0开 始针对多线程并发访问设计,提供了并发性能较好的并发容器,引入

【转】Java并发编程:并发容器之ConcurrentHashMap

JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了并发性,当多个线程竞争容器时,吞吐量严重降低.因此Java5.0开始针对多线程并发访问设计,提供了并发性能较好的并发容器,引入了java.util.concurrent包.与Vector和Hashtable.Collections.synchronizedXxx()同步容器等相比,util.conc