BADWOLFBAY

Run,You Clever Boy!


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

Java多线程synchronized

发表于 2017-12-06 | 分类于 Java

synchronized依靠锁机制实现多线程的同步,锁分两种

  • 对象锁
  • 类锁

1.synchronized作用于普通方法时依靠对象锁工作,多线程访问synchronized方法,一旦某个线程抢到锁后,其他进程排队等待
等效于

1
2
3
4
void method{
synchronized(this){
}
}

示例:

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
public class TestSynchronized {
public synchronized void method1() throws InterruptedException {
System.out.println("Method1 start at :" + System.currentTimeMillis());
Thread.sleep(6000);
System.out.println("Method1 end at :" + System.currentTimeMillis());
}
public synchronized void method2() throws InterruptedException {
while (true) {
System.out.println("method2 running");
Thread.sleep(200);
}
}
static TestSynchronized instance = new TestSynchronized();
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
instance.method1();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 1; i < 4; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread1 still alive");
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
instance.method2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
}

方法method2会一直等待method1执行完成后再执行。
synchronized void method(){}整个函数加上synchronized块,效率并不好。

2.synchronized作用于静态方法相当于

1
2
3
4
void method(){
synchronized(Object.class){
}
}

JVM学习一

发表于 2017-11-15 | 分类于 Java

OutOfMemoryError异常

JAVA堆溢出

Java堆用来存储对象实例,只要不断的创建对象,只要在对象数量达到最大堆的容量限制后就会产生内存溢出

通过设置堆的最小值(-Xms)参数和最大值(-Xmx)设置相等来避免堆自动扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
// VM args -Xmx20m -Xms20m
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args){
List<OOMObject> list = new ArrayList<>();
while(true){
list.add(new OOMObject());
}
}
}

报错信息

1
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

虚拟机栈和本地方法溢出

在HotSpot虚拟机中并不区分虚拟机栈和本地方法栈
栈容量只能通过-Xss来设置
存放基本数据类型(byte,char,boolean,shot,int,long,float,double)和对象的引用类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// VM args -Xss128k
public class JavaVMStackSOF {
private int stackLength = -1;
public void stackLeak(){
stackLength++;
stackLeak();
}
public static void main(String[] args){
JavaVMStackSOF oom = new JavaVMStackSOF();
try{
oom.stackLeak();
}catch(Throwable e){
System.out.println("stack length:" + oom.stackLength);
throw e;
}
}
}
阅读全文 »

HashMap总结

发表于 2017-11-15 | 分类于 Java
  • 基于Map接口实现,允许null键/值,非同步(线程不安全),不保证有序,也不保证顺序不随时间变化;存储着Entry(hash,key,value,next)对象
  • 两个重要参数容量(Capacity)和负载因子(Load factor)
  • HashMap在new后并不会分配数组,而是在第一次put时进行初始化,类似ArrayList在第一次add时分配内存空间
  • HashMap的bucket数组大小一定是2的幂,如果是new的时候指定了容量且不是2的幂,实际容量会是最接近且大于指定容量的2的幂,如new HashMap<>(19),实际容量为32
  • HashMap在put的元素大于Capacity*LoadFactor(默认16*0.75)之后会进行扩容
  • JDK8处于提升性能的考虑,在哈希碰撞的链表长度达到TREEIFY_THRESHOLD(默认8)后,会把该链表转变成树结构
  • JDK8在resize的时候,通过巧妙的设计,减少了rehash的性能消耗;resize是扩容的两倍

http://yikun.github.io

Go指南学习笔记十三

发表于 2017-11-08 | 分类于 golang

range和close

发送者可以通过close来关闭channel。
接受者可以通过传入第二个参数来测试channl是否被关闭

1
v, ok := <-ch

循环for i := range c会不断从channl接受值,直到它被关闭。

只有发送者能关闭channel,而不是接收者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main
import (
"fmt"
)
//斐波那契数列
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
close(c)
}
func main(){
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}

输出结果

1
2
3
4
5
6
7
8
9
10
0
1
1
2
3
5
8
13
21
34
阅读全文 »

Go指南学习笔记十二

发表于 2017-11-07 | 分类于 golang

goroutine

goroutine是Go运行时环境管理的轻量级线程

go f(x,y,z)

开启一个新的goroutine执行。

f,x,y,z是在当前goroutine中定义的,但是在新的goroutine中运行f。

goroutine在相同的地址空间中运行,因此访问共享内存必须同步。sync提供了这种可能,不过在Go中并不经常用到,因为还有其他办法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import (
"fmt"
"time"
)
func say(s string) {
for i:=0; i<5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}

运行结果,hello和world交替运行。

1
2
3
4
5
6
7
8
9
10
11
[Running] go run "f:\study\go\smp\src\goroutine.go"
world
hello
hello
world
hello
world
hello
world
world
hello
阅读全文 »

百度Java面试题汇总

发表于 2017-10-26 | 分类于 Java

简单记录下百度Java面试题

  • Java源码使用了哪些设计模式?列举你知道的类/包以及使用模式
  • 写一个单例模式
  • Threadlocal有哪些特点,描述使用场景
  • 快速排序
  • Mysql事务隔离级别(Spring事务隔离级别)
  • 字符串常量池
  • 类加载器
  • SpringMVC和Struts2有什么区别?(需要跟进新技术,为什么SpringMVC替代Struts2)
  • Java,Python和Go三个相比各自有什么优点和缺点(需要自己总结思考)
  • 网络传输,应用层有哪些协议?(并问了Http头的详细信息)
  • 设计一个互联网架构
  • 接上:当访问量多比如秒杀可能的瓶颈在哪里,怎么解决这些瓶颈问题
  • 数据库怎么读写分离,怎么分库分表
  • Java中HashMap的containsKey和containsValue的时间复杂度
  • 线程池的最大线程数和核心线程数
  • Spring事务的处理及回滚机制(事务的一致性)
  • JAVA的装饰者模式和IO流
  • Mybatis插入的返回值
  • Synchrosized的静态方法和普通方法上的区别
  • 时间复杂度/空间复杂度

需要自己接下来深入学习JVM,网络层。
由底层原理–>架构–>项目/应用/数据/性能

Go指南学习笔记十一

发表于 2017-10-25 | 分类于 golang

错误

Go使用error来标识错误状态。
同fmt.Stringer一样,error类型也是个内建接口。

1
2
3
type error interface {
Error() string
}

通常函数会返回一个error值,调用它的代码应判断这个错误是否等于nil来进行错误处理。

1
2
3
4
5
6
7
i, err := strconv.Atoi("42")
if err != nil {
fmt.Printf("conldn't convert number: %v\n", err)
return
}
fmt.Printfln("Converted integer:", i)

error为nil时表示成功;非nil的error表示错误

阅读全文 »

非root用户运行docker

发表于 2017-10-13 | 分类于 docker

转载:

原文出处:

https://notes.wanghao.work/2017-07-11-Docker非Root用户运行.html


Docker Engine的Deamon进程是以root权限运行的,如果是普通用户要与之交互,需要使用sudo命令来提权与之交互。之前使用Docker官方的安装脚本安装完成之后,会给出一个提示将当前非root用户添加到doker组之中,以避免每次都需要输入sudo的麻烦。

然而随着Docker版本的迭代和官网的安装方式的更改,现在官方给出的安装方式是添加仓库源地址,然后使用默认的apt或者yum包管理工具来完成后安装。并不再提示用户添加非root用户到组。

默认情况下,完成Docker Engine的安装之后,Docker将会自动创建一个名为docker的用户组,所以root用户和在docker组中的用户都可以免去sudo来与Docker Engine交互。知道原理之后就简单了:

1
sudo usermod -aG docker ${whoami} #添加当前用户到docker组

Go指南学习笔记十

发表于 2017-10-12 | 分类于 golang

Stringers

普遍存在的接口是fmt包中定义的Stringer

1
2
3
type Stringer inferface {
String() string
}

Stringer是一个可以用字符串描述自己的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
func main() {
a := Person{"Dent", 42}
z := Person{"Foo", 90}
fmt.Println(a, z) // 输出Dent (42 years) Foo (90 years)
}

Kubernetes网络组件Calico安装

发表于 2017-09-26 | 分类于 docker

参照官网地址:

https://docs.projectcalico.org/v2.5/getting-started/kubernetes/installation/integration

Calico组件包括

  • calico/node, 必须安装在Master节点和每个计算节点上,包括BGP agent,负责网络策略。
  • cni/plugin, 和kubelet交互发现pod。
  • calico/policy-controller ,实现kubernetes的Network Policy API.

本文中安装的calico版本为2.5,对应的组件版本分别为:

calicoctl:v1.5.0
cni-plugin:v1.10.0
cni:v0.3.0

安装calico/node

1
2
3
4
5
$ wget https://github.com/projectcalico/calicoctl/releases/download/v1.5.0/calicoctl
$ sudo chmod +x calicoctl
$ mv calicoctl /usr/bin

创建calico-node.service

1
$ vi /usr/lib/systemd/system/calico-node.service

service的内容,需要将ETCD_ENDPOINTS中地址换成真实的etcd集群地址,可以将node-image中指定所需要的镜像名称,如果不指定,默认为quay.io/calico/node:latest

下边的命令会导致calio-node一直重启,所以需要换成官网的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=calicoctl node
After=docker.service
Requires=docker.service
[Service]
User=root
Environment=ETCD_ENDPOINTS=http://172.21.1.201:2379
PermissionsStartOnly=true
ExecStart=/usr/bin/calicoctl node run --node-image=calico/node:v2.5.1
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

换成(替换下边的ETCD_ENDPOINTS和ExecStart命令中的镜像名称)

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
[Unit]
Description=calico node
After=docker.service
Requires=docker.service
[Service]
User=root
Environment=ETCD_ENDPOINTS=http://<ETCD_IP>:<ETCD_PORT>
PermissionsStartOnly=true
ExecStart=/usr/bin/docker run --net=host --privileged --name=calico-node \
-e ETCD_ENDPOINTS=${ETCD_ENDPOINTS} \
-e NODENAME=${HOSTNAME} \
-e IP= \
-e NO_DEFAULT_POOLS= \
-e AS= \
-e CALICO_LIBNETWORK_ENABLED=true \
-e IP6= \
-e CALICO_NETWORKING_BACKEND=bird \
-e FELIX_DEFAULTENDPOINTTOHOSTACTION=ACCEPT \
-v /var/run/calico:/var/run/calico \
-v /lib/modules:/lib/modules \
-v /run/docker/plugins:/run/docker/plugins \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/log/calico:/var/log/calico \
calico/node:v2.5.1
ExecStop=/usr/bin/docker rm -f calico-node
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

启动calico-node服务

1
2
$ systemctl daemon-reload
$ systemctl start calico-node

查看服务启动情况以及容器启动情况

1
2
3
4
5
6
7
8
9
10
11
12
$ systemctl status calico-node
● calico-node.service - calicoctl node
Loaded: loaded (/usr/lib/systemd/system/calico-node.service; disabled; vendor preset: disabled)
Active: activating (auto-restart) since Tue 2017-09-26 09:57:00 CST; 1s ago
Process: 23696 ExecStart=/usr/bin/calicoctl node run --node-image=calico/node:v2.5.1 (code=exited, status=0/SUCCESS)
Main PID: 23696 (code=exited, status=0/SUCCESS)
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1cca427ef1a1 calico/node:v2.5.1 "start_runit" 10 seconds ago Up 9 seconds calico-node
阅读全文 »
123…5
badwolf

badwolf

Run,You Clever Boy!

43 日志
12 分类
16 标签
RSS
Links
  • badwolfbay
  • Gluon-deepmind
  • 浮生志
© 2020 badwolf
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.2