docker修改运行的容器端口

前言

有时候docker容器已经运行了,发现端口占用或者冲突了,不方便删除重新运行容器,可以通过修改配置文件方式来调整端口

1、Linux

1.1 先停止容器

1
docker stop {容器的名称或者id}

1.2 然后查询完整的容器id

1
2
3
4
docker inspect {容器的名称或者id} | grep Id

# 比如如下示例
"Id": "cbe26510c276fa9a4487a8c2af8cbb49410f2a5305149d2b26eb8ce37c777d00"

1.3 打开hostconfig.json配置文件

1
2
3
4
vi /var/lib/docker/containers/{hash_of_the_container}/hostconfig.json

# 比如示例的Id
vi /var/lib/docker/containers/cbe26510c276fa9a4487a8c2af8cbb49410f2a5305149d2b26eb8ce37c777d00/hostconfig.json

1.4 还有不用完整的容器id也可以(可选,跟1.3相同)

1
2
3
4
5
6
cd /var/lib/docker/containers/{hash_of_the_container}*

# 比如示例的
cd /var/lib/docker/containers/cbe26510c276*

vi hostconfig.json

1.5 修改hostconfig.json配置文件

在 hostconfig.json 配置文件中,找到 “PortBindings”:{} 这个配置项,然后进行修改。 HostPort 对应的端口代表 宿主机 的端口。

……

阅读全文

ID生成方案对比:UUID、UDID、NanoID与ULID

前言

做分布式系统或设计表主键时总要面对「用什么生成唯一 ID」的问题。UUID 不是唯一选项——ULID、NanoID 都在特定场景下更有优势。这篇把四个常见方案放在一起对比。

一、UDID:设备的身份证

UDID(Unique Device Identifier,设备唯一标识符)只和设备有关,类似 MAC 地址。iOS 真机调试时需要把 UDID 加进 Provisioning Profile 授权文件来识别设备。UDID 是一个 40 位十六进制序列,可以通过 iTunes 和 Xcode 获取。

……

阅读全文

go多版本管理工具

前言

在本地新旧项目并行开发的过程中,你大概率会遇到一个令人头疼的问题,如何同时使用两个不同版本的 Golang Runtime 进行开发呢?

在容器和 CI 流行的当前时代下,我们似乎已经习惯了用 docker run 来切换各种语言的版本,来完成不同项目的开发,基础类型项目的兼容性测试。配合一些支持远程调试的工具,体验似乎也还行。

但是在运行效率和复杂度上,相比本地环境而言,总归是高了那么一丢丢。

……

阅读全文

jenkins的admin密码忘记了如何重置

前言

最近项目比较忙,没时间记录一些日常的心得,慢慢整理一些吧。正好9月份碰到一个交接的项目和服务器,发现服务器占用率很低,找运维重置了密码后登录检查服务,发现部署工具jenkins没人知道admin密码,于是重置了admin密码,记录下步骤

1、删除配置项

找到下面的配置项并注释

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!-->
  <useSecurity>true</useSecurity>
  <authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
    <denyAnonymousReadAccess>true</denyAnonymousReadAccess>
  </authorizationStrategy>
  <securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
    <disableSignup>true</disableSignup>
    <enableCaptcha>false</enableCaptcha>
  </securityRealm>
<-->

2、重启Jenkins服务

1
2
3
4
5
ps -ef | grep jekins

kill -9 22092

/usr/java/jdk1.8.0_192/bin/java -Dcom.sun.akuma.Daemon=daemonized -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --daemon --httpPort=8321 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20 &

3、系统管理

进入首页>“系统管理”>“Configure Global Security”

……

阅读全文

docker网络模式

前言

docker 的网络模式整理

1、查看所有容器的 IP

1
docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
/etcd - 172.17.0.6
/minio1 - 172.17.0.2
/getting-started-latest - 172.17.0.3
/nginx1.22.0 - 172.17.0.12
/go-docker-v1 - 172.17.0.9
/java-docker-v1 - 172.17.0.7
/nodejs-docker-v1 - 172.17.0.8
/python-docker-v1 - 172.17.0.4
/mongo6 - 172.17.0.11
/redis7 - 172.17.0.5
/mysql8 - 172.17.0.10

2、查看指定容器的ip网络配置包含网络,ip等

1
docker inspect containerId
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
$ docker inspect b055811ce23c
[
    {
        "Id": "b055811ce23cf53d3b5e2cf193c0cd4a22a5befbf101bdd940662ecbe64ccc2c",
        "Created": "2022-09-06T08:50:31.6648081Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "mysqld"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 2724,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-09-17T12:02:29.756584113Z",
            "FinishedAt": "2022-09-17T12:02:27.248114859Z"
        },
        "Image": "sha256:ff3b5098b416cc4294d8d5c43c2f0f8251e91711347318e73cb290ffe2783bcb",
        "ResolvConfPath": "/var/lib/docker/containers/b055811ce23cf53d3b5e2cf193c0cd4a22a5befbf101bdd940662ecbe64ccc2c/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/b055811ce23cf53d3b5e2cf193c0cd4a22a5befbf101bdd940662ecbe64ccc2c/hostname",
        "HostsPath": "/var/lib/docker/containers/b055811ce23cf53d3b5e2cf193c0cd4a22a5befbf101bdd940662ecbe64ccc2c/hosts",
        "LogPath": "/var/lib/docker/containers/b055811ce23cf53d3b5e2cf193c0cd4a22a5befbf101bdd940662ecbe64ccc2c/b055811ce23cf53d3b5e2cf193c0cd4a22a5befbf101bdd940662ecbe64ccc2c-json.log",
        "Name": "/mysql8",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": [
                "/Users/Downloads/Docker/mysql/config/my.cnf:/etc/mysql/my.cnf",
                "/Users/Downloads/Docker/mysql/data:/usr/data",
                "/Users/Downloads/Docker/mysql/log:/logs",
                "/Users/Downloads/Docker/mysql/localtime:/etc/localtime"
            ],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "bridge",
            "PortBindings": {
                "3306/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "3306"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "always",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": true,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
                "label=disable"
            ],
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": null,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": null,
            "ReadonlyPaths": null
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/262b7fe49ceef30a815f7acd398efd160a8575276a26bd3ed5fe8d03b89c64f5-init/diff:/var/lib/docker/overlay2/f9793fa9c30e39c82416c7664ba9f1bded7164da0eedc04db5f9d34e8ae524bd/diff:/var/lib/docker/overlay2/8bd9971c98c7afafafb6af93fe793eb01881a3e28a25e166cce5037d1867f3a6/diff:/var/lib/docker/overlay2/718e2486037cff064644cfe79f7e0710364ed8b18a2813c501fc921872e154a7/diff:/var/lib/docker/overlay2/d4239c0d55a03ec8e29d9e7a4fcd7aab5f081c4a564eb341d1065f9d0df24429/diff:/var/lib/docker/overlay2/e393d409b7557dac52f8e497f8743ef9663b6037abe9a4edd8cdd66bad9de964/diff:/var/lib/docker/overlay2/1bb134141159fe08fa4dc08b7404e92b103242319663ecee72f5e4aff61c3a40/diff:/var/lib/docker/overlay2/ed42a23c02fe373db201fcc49bf0bd80ee663766ac400aa101163a42ea6ba469/diff:/var/lib/docker/overlay2/d4e972b8eae083ea8c8dc28538c2d92b2e63e4849c348e47783725cbfd42eafa/diff:/var/lib/docker/overlay2/b23c6d2cb95f018ab8ade60d15a40f9bd4eca5568cdae22b10a75b4b22bb8608/diff:/var/lib/docker/overlay2/36e999dce4bab3eee5d5a74b607ee845ebd8b95707222b9f0e57f5d40922b1ce/diff:/var/lib/docker/overlay2/b0f8ffee4114eb3d1797566ab320c34e38e71780e532cadb8d327f03c5a49593/diff",
                "MergedDir": "/var/lib/docker/overlay2/262b7fe49ceef30a815f7acd398efd160a8575276a26bd3ed5fe8d03b89c64f5/merged",
                "UpperDir": "/var/lib/docker/overlay2/262b7fe49ceef30a815f7acd398efd160a8575276a26bd3ed5fe8d03b89c64f5/diff",
                "WorkDir": "/var/lib/docker/overlay2/262b7fe49ceef30a815f7acd398efd160a8575276a26bd3ed5fe8d03b89c64f5/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/Downloads/Docker/mysql/localtime",
                "Destination": "/etc/localtime",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/Downloads/Docker/mysql/config/my.cnf",
                "Destination": "/etc/mysql/my.cnf",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/Downloads/Docker/mysql/log",
                "Destination": "/logs",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/Users/Downloads/Docker/mysql/data",
                "Destination": "/usr/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "volume",
                "Name": "eda1141a1129e17676fc14b6cfedc975c01b8cef030d3042df9543ae0c133ba6",
                "Source": "/var/lib/docker/volumes/eda1141a1129e17676fc14b6cfedc975c01b8cef030d3042df9543ae0c133ba6/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "b055811ce23c",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "3306/tcp": {},
                "33060/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "MYSQL_PASSWORD=test123456",
                "character-set-server=utf8",
                "collation-server=utf8_general_ci",
                "MYSQL_ROOT_PASSWORD=root123456",
                "MYSQL_USER=mysql",
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.14",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.30-1.el8",
                "MYSQL_SHELL_VERSION=8.0.30-1.el8"
            ],
            "Cmd": [
                "mysqld"
            ],
            "Image": "mysql:8.0",
            "Volumes": {
                "/var/lib/mysql": {}
            },
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "c6b894c6e93f77d1373c596b7e0b739e9077496ae8fd0f9ac4a0e332cd9ff64b",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "3306/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "3306"
                    }
                ],
                "33060/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/c6b894c6e93f",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "632055c898d3becb5e76e5216cd471daed266f115ab84c18dd4f64da4adbf189",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.8",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:08",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "df04e694c73a176ccca94ab55253f9ac8937658faf87c4a23a1215e98c114e28",
                    "EndpointID": "632055c898d3becb5e76e5216cd471daed266f115ab84c18dd4f64da4adbf189",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.8",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:08",
                    "DriverOpts": null
                }
            }
        }
    }
]
$

3、查看容器的ip

1
docker exec -it containerId ip addr
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 类似ip addr命令执行,需要带ip 命令才可以执行,否则会报错,下面样例仅供参考
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 00:50:56:87:3e:b8 brd ff:ff:ff:ff:ff:ff
    inet 10.10.235.111/24 brd 10.10.235.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe87:3eb8/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:b2:e3:13:75 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.1/24 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:b2ff:fee3:1375/64 scope link 
       valid_lft forever preferred_lft forever
7: vethaaab889@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 8e:8e:10:a1:a0:92 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::8c8e:10ff:fea1:a092/64 scope link 
       valid_lft forever preferred_lft forever
9: veth56dcf1b@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 6e:ac:31:5f:68:32 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::6cac:31ff:fe5f:6832/64 scope link 
       valid_lft forever preferred_lft forever
15: veth6e7ba4f@if14: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 22:ba:45:08:19:78 brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::20ba:45ff:fe08:1978/64 scope link 
       valid_lft forever preferred_lft forever
You have new mail in /var/spool/mail/root

4、docker 的网络模式及区别

4.1 docker的四种网络模式

None — 不为容器进行任何网络配置,容器不能访问外部网络,内部存在回路地址,这个Docker容器没有网卡、IP、路由等信息,只有lo 网络接口。需要我们自己为Docker容器添加网卡、配置IP等。

……

阅读全文

dockerfile

前言

dockerfile学习整理

一、概述

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

官方文档
Dockerfile示例

二、Dockerfile结构

Dockerfile结构主要分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令 (CMD/ENTRYPOINT)

【温馨提示】Dockerfile每行支持一条指令,每条指令可携带多个参数(支持&&),支持使用以“#“号开头的注释(jason文件不支持#注释),但是也非必须满足上面的四点。

……

阅读全文

Mac配置docker开发工具

前言

2020年整了一套android下的termux开发环境,今天继续配置一套docker下的开发环境。termux搭建参考

开发电脑环境准备如下:

系统 版本
MacOS 10.14.6
docker 20.10.12

待安装的开发工具环境如下:

镜像 版本
mongo 6.0
redis 7.0
mysql 8.0
nginx 1.22.0
minio latest
etcd latest

1、查询docker进程

1
2
3
launchctl list | grep docker
-	0	com.docker.helper
14047	0	com.docker.docker.47840

2、停止、启动docker进程

1
launchctl stop com.docker.docker.47840 && launchctl start com.docker.docker.47840

3、启动docker

1
open /Applications/Docker.app

PS:

目前通过 open /Applications/Docker.app 可以启动,通过 launchctl start com.docker.docker.xxx 方式不能启动了。

……

阅读全文

转载-arthas常见用法

前言

Arthas是Alibaba开源的Java诊断工具,动态跟踪Java代码;实时监控JVM状态,可以在不中断程序执行的情况下轻松完成JVM相关问题排查工作 。支持JDK 6+,支持Linux/Mac/Windows。这个工具真的很好用,而且入门超简单,十分推荐。

1、使用场景

  • 1、这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  • 2、我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  • 3、遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  • 4、线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  • 5、是否有一个全局视角来查看系统的运行状况?
  • 6、有什么办法可以监控到JVM的实时运行状态?接下来,围绕这6个问题,学习下Arthas的基本用法。

2、安装

执行下面命令下载

……

阅读全文

java锁体系与ReentrantLock详解

前言

面试和实际编码里 java 锁都是绕不开的话题。这篇先按维度把常见锁的分类理清楚,再聚焦 ReentrantLock:它的四个高级特性分别解决 synchronized 的什么短板,配可运行的验证代码,最后是核心方法与注意事项。

一、java 常见锁的七种分类

按不同维度,锁可以分成下面几组——同一把锁在不同维度下有不同名字:

维度 分类 说明
竞争是否排队 公平锁 / 非公平锁 synchronized 和 ReentrantLock 默认都是非公平锁,非公平可以避免线程唤醒的空档期、提高吞吐
同线程能否重复获取 可重入锁 / 不可重入锁 ReentrantLock 对同一线程可重入,不会自己锁死自己
能否被多线程共享 共享锁 / 独占锁 ReentrantReadWriteLock 中读锁是共享锁、写锁是排他锁
等待期能否被中断 可中断锁 / 不可中断锁 ReentrantLock 的 lockInterruptibly() 支持中断
是否锁住资源 悲观锁 / 乐观锁 synchronized 是悲观;CAS(如 Atomic 系列)是乐观
等待方式 自旋锁 / 阻塞锁 自旋避免上下文切换,但空耗 CPU
- 偏向锁/轻量级锁/重量级锁 synchronized 的锁升级路径(JDK 15 起偏向锁已废弃)

二、ReentrantLock 的四个高级特性

ReentrantLock 实现了 Lock 接口,作用与 synchronized 一样是线程安全,但多了四个 synchronized 没有的能力。

……

阅读全文

几种id浅谈

前言

几种 ID 浅谈,UDID、UUID、ULID、NanoID

1、UDID

Unique Device Identifier(设备唯一标识符)
从名称上也可以看出,UDID这个东西是和设备有关的,而且是只和设备有关的,有点类似于MAC地址。真机调试,然后需要把UDID这个东西添加到Provisoning Profile授权文件中,也就是把设备唯一标识符添加进去,以此来识别某一台设备。 UDID是一个40位十六进制序列,我们可以使用iTunes和Xcode来获取这个值。

……

阅读全文

最近文章

分类

标签

其它