Skip to content

Commit 2c1fcf9

Browse files
committed
cache
1 parent 22e2679 commit 2c1fcf9

File tree

7 files changed

+259
-187
lines changed

7 files changed

+259
-187
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package jvm.gc.g1;
2+
3+
/**
4+
* @author https://github.com/kuangcp on 2021-08-30 03:33
5+
*/
6+
public class DesignRegionSize {
7+
}

class/src/main/java/jvm/gc/g1/StringDeduplication.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44

55
/**
66
* @author https://github.com/kuangcp on 2021-05-16 23:36
7-
*
7+
* <p>
88
* -Xms15m -Xmx15m -XX:+PrintGCDetails -XX:+UseG1GC -XX:+PrintStringTableStatistics -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics
99
*/
1010
public class StringDeduplication {
1111

12-
// TODO 如何设计用例 体现去重特性
13-
public static void main(String[] args) throws InterruptedException {
14-
for (int j = 0; j < 100; j++) {
15-
for (int i = 0; i < 1000; i++) {
16-
String.valueOf(i).intern();
17-
}
18-
TimeUnit.MILLISECONDS.sleep(30);
12+
// TODO 如何设计用例 体现去重特性
13+
public static void main(String[] args) throws InterruptedException {
14+
for (int j = 0; j < 100; j++) {
15+
for (int i = 0; i < 1000; i++) {
16+
String.valueOf(i).intern();
17+
}
18+
TimeUnit.MILLISECONDS.sleep(30);
19+
}
1920
}
20-
}
2121
}
Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,55 @@
11
package time;
22

33

4-
import static org.hamcrest.Matchers.lessThan;
5-
import static org.junit.Assert.assertThat;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.junit.Test;
66

77
import java.time.LocalDateTime;
88
import java.time.ZoneOffset;
9-
import lombok.extern.slf4j.Slf4j;
10-
import org.junit.Test;
9+
import java.util.Date;
10+
11+
import static org.hamcrest.Matchers.lessThan;
12+
import static org.junit.Assert.assertThat;
1113

1214
/**
1315
* @author kuangcp on 18-9-11-下午3:52
1416
* LocalDateTime 本身是和时区没有关联的,
1517
* 如果是采用 now() 得到LocalDateTime的实例 就会采用操作系统默认时区
1618
* 如果是采用 of() 得到LocalDateTime的实例 就不会和时区有关系, 采用默认的UTC
17-
*
19+
* <p>
1820
* LocalDateTime 就是 主要由 LocalDate LocalTime 组成的对象, 唯一的私有构造器就说明了这一点
1921
*/
2022
@Slf4j
2123
public class LocalDateTimeTest {
2224

23-
@Test
24-
public void testNow() {
25-
// 这里默认使用了当前时区 计算得到时间
26-
LocalDateTime now = LocalDateTime.now();
25+
@Test
26+
public void testNow() {
27+
// 这里默认使用了当前时区 计算得到时间
28+
LocalDateTime now = LocalDateTime.now();
29+
30+
// 这里将时区的影响消除
31+
long milli = now.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
32+
33+
log.info(": milli={}", milli);
34+
log.info(": milli={}", System.currentTimeMillis());
2735

28-
// 这里将时区的影响消除
29-
long milli = now.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
36+
// 这个差就是以上转换消耗的时间
37+
assertThat(System.currentTimeMillis() - milli, lessThan(10L));
38+
}
3039

31-
log.info(": milli={}", milli);
32-
log.info(": milli={}", System.currentTimeMillis());
40+
@Test
41+
public void testOf() {
42+
LocalDateTime of = LocalDateTime.of(2018, 1, 23, 22, 22);
43+
log.info(": of={}", of.toString());
44+
String instant = of.atZone(ZoneOffset.systemDefault()).toInstant().toString();
45+
log.info(": instant={}", instant);
46+
}
3347

34-
// 这个差就是以上转换消耗的时间
35-
assertThat(System.currentTimeMillis() - milli, lessThan(10L));
36-
}
48+
@Test
49+
public void testDate() throws Exception {
50+
final Date date = new Date(585327600000L);
51+
System.out.println(date);
3752

38-
@Test
39-
public void testOf() {
40-
LocalDateTime of = LocalDateTime.of(2018, 1, 23, 22, 22);
41-
log.info(": of={}", of.toString());
42-
String instant = of.atZone(ZoneOffset.systemDefault()).toInstant().toString();
43-
log.info(": instant={}", instant);
44-
}
53+
}
4554

4655
}

class/src/test/java/time/Readme.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Java8 中有关时间的类
22

3+
Java中时间戳为0时表示的时间是1970-01-01 00:00:00 由于 Date类是和时区有关的,所以实例化的时候会带上时区信息,格式化输出也会带上时区
4+
但是System.currentTimeMillis()就是时区无关的时间戳。
5+
以及Java8新增的LocalDateTime等类of()方式实例化都是不带时区信息,但是now()方式实例化不一样,会依据当前时间戳以及时区信息转换得到相对时间戳
6+
7+
```java
8+
System.out.println(new Date(0)); // Thu Jan 01 08:00:00 CST 1970
9+
```
10+
11+
- 时区有关 Date
12+
- 时区无关 LocalDateTime LocalDate LocalTime
13+
314
- java.time 包下
415

516
```
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package guava.ratelimit;
2+
3+
import com.google.common.util.concurrent.RateLimiter;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.junit.Test;
6+
7+
import java.util.concurrent.TimeUnit;
8+
9+
/**
10+
* @author <a href="https://github.com/kuangcp">Kuangcp</a> on 2021-08-30 03:00
11+
*/
12+
@Slf4j
13+
public class RateLimiterTest {
14+
15+
@Test
16+
public void testLimit1() throws Exception {
17+
final RateLimiter rateLimiter = RateLimiter.create(3, 5, TimeUnit.SECONDS);
18+
rateLimiter.acquire();
19+
20+
// SmoothRateLimiter
21+
new Thread(() -> {
22+
for (int i = 0; i < 1000; i++) {
23+
try {
24+
TimeUnit.MILLISECONDS.sleep(100);
25+
rateLimiter.acquire();
26+
log.info("run");
27+
} catch (InterruptedException e) {
28+
log.error("", e);
29+
}
30+
}
31+
}).start();
32+
33+
TimeUnit.HOURS.sleep(1);
34+
}
35+
}

netty/src/main/java/netty/websocket/NioWebSocketHandler.java

Lines changed: 95 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -7,130 +7,121 @@
77
import io.netty.channel.ChannelFutureListener;
88
import io.netty.channel.ChannelHandlerContext;
99
import io.netty.channel.SimpleChannelInboundHandler;
10-
import io.netty.handler.codec.http.DefaultFullHttpResponse;
11-
import io.netty.handler.codec.http.FullHttpRequest;
12-
import io.netty.handler.codec.http.HttpResponseStatus;
13-
import io.netty.handler.codec.http.HttpUtil;
14-
import io.netty.handler.codec.http.HttpVersion;
15-
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
16-
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
17-
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
18-
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
19-
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
20-
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
21-
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
10+
import io.netty.handler.codec.http.*;
11+
import io.netty.handler.codec.http.websocketx.*;
2212
import io.netty.util.CharsetUtil;
23-
import java.util.Date;
2413
import lombok.extern.slf4j.Slf4j;
2514

15+
import java.util.Date;
16+
2617
/**
2718
* @author https://github.com/kuangcp on 2021-05-18 08:33
2819
*/
2920
@Slf4j
3021
public class NioWebSocketHandler extends SimpleChannelInboundHandler<Object> {
3122

32-
private WebSocketServerHandshaker handshaker;
33-
34-
@Override
35-
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
36-
log.debug("收到消息:" + msg);
37-
if (msg instanceof FullHttpRequest) {
38-
//以http请求形式接入,但是走的是websocket
39-
handleHttpRequest(ctx, (FullHttpRequest) msg);
40-
} else if (msg instanceof WebSocketFrame) {
41-
//处理websocket客户端的消息
42-
handlerWebSocketFrame(ctx, (WebSocketFrame) msg);
43-
}
44-
}
45-
46-
@Override
47-
public void channelActive(ChannelHandlerContext ctx) throws Exception {
48-
log.debug("客户端加入连接:" + ctx.channel());
49-
ChannelSupervise.addChannel(ctx.channel());
50-
}
51-
52-
@Override
53-
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
54-
log.debug("客户端断开连接:" + ctx.channel());
55-
ChannelSupervise.removeChannel(ctx.channel());
56-
}
57-
58-
@Override
59-
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
60-
ctx.flush();
61-
}
62-
63-
private void handlerWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
64-
// 判断是否关闭链路的指令
65-
if (frame instanceof CloseWebSocketFrame) {
66-
handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
67-
return;
23+
private WebSocketServerHandshaker handshaker;
24+
25+
@Override
26+
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
27+
log.debug("收到消息:" + msg);
28+
if (msg instanceof FullHttpRequest) {
29+
//以http请求形式接入,但是走的是websocket
30+
handleHttpRequest(ctx, (FullHttpRequest) msg);
31+
} else if (msg instanceof WebSocketFrame) {
32+
//处理websocket客户端的消息
33+
handlerWebSocketFrame(ctx, (WebSocketFrame) msg);
34+
}
6835
}
6936

70-
// 判断是否ping消息
71-
if (frame instanceof PingWebSocketFrame) {
72-
ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
73-
return;
37+
@Override
38+
public void channelActive(ChannelHandlerContext ctx) throws Exception {
39+
log.debug("客户端加入连接:" + ctx.channel());
40+
ChannelSupervise.addChannel(ctx.channel());
7441
}
7542

76-
// 本例程仅支持文本消息,不支持二进制消息
77-
if (!(frame instanceof TextWebSocketFrame)) {
78-
log.debug("本例程仅支持文本消息,不支持二进制消息");
79-
throw new UnsupportedOperationException(String.format(
80-
"%s frame types not supported", frame.getClass().getName()));
43+
@Override
44+
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
45+
log.debug("客户端断开连接:" + ctx.channel());
46+
ChannelSupervise.removeChannel(ctx.channel());
8147
}
8248

83-
// 返回应答消息
84-
String request = ((TextWebSocketFrame) frame).text();
85-
log.debug("服务端收到:" + request);
86-
TextWebSocketFrame tws = new TextWebSocketFrame(
87-
new Date().toString() + ctx.channel().id() + ":" + request);
49+
@Override
50+
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
51+
ctx.flush();
52+
}
8853

89-
// 群发至所有连接
54+
private void handlerWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
55+
// 判断是否关闭链路的指令
56+
if (frame instanceof CloseWebSocketFrame) {
57+
handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
58+
return;
59+
}
60+
61+
// 判断是否ping消息
62+
if (frame instanceof PingWebSocketFrame) {
63+
ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
64+
return;
65+
}
66+
67+
// 本例程仅支持文本消息,不支持二进制消息
68+
if (!(frame instanceof TextWebSocketFrame)) {
69+
log.debug("本例程仅支持文本消息,不支持二进制消息");
70+
throw new UnsupportedOperationException(String.format(
71+
"%s frame types not supported", frame.getClass().getName()));
72+
}
73+
74+
// 返回应答消息
75+
String request = ((TextWebSocketFrame) frame).text();
76+
log.info("服务端收到:final:{} txt:{}", frame.isFinalFragment(), request.length());
77+
TextWebSocketFrame tws = new TextWebSocketFrame(
78+
new Date().toString() + ctx.channel().id() + ":" + request);
79+
80+
// 群发至所有连接
9081
// ChannelSupervise.send2All(tws);
9182

92-
// 返回【谁发的发给谁】
93-
ctx.channel().writeAndFlush(tws);
94-
}
95-
96-
/**
97-
* 唯一的一次http请求,用于创建websocket
98-
*/
99-
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
100-
//要求Upgrade为websocket,过滤掉get/Post
101-
if (!req.decoderResult().isSuccess()
102-
|| (!"websocket".equals(req.headers().get("Upgrade")))) {
103-
//若不是websocket方式,则创建BAD_REQUEST的req,返回给客户端
104-
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(
105-
HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
106-
return;
83+
// 返回【谁发的发给谁】
84+
ctx.channel().writeAndFlush(tws);
10785
}
10886

109-
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
110-
"ws://localhost:7094/ws", null, false);
111-
handshaker = wsFactory.newHandshaker(req);
112-
if (handshaker == null) {
113-
WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
114-
} else {
115-
handshaker.handshake(ctx.channel(), req);
116-
}
117-
}
118-
119-
/**
120-
* 拒绝不合法的请求,并返回错误信息
121-
*/
122-
private static void sendHttpResponse(ChannelHandlerContext ctx,
123-
FullHttpRequest req, DefaultFullHttpResponse res) {
124-
// 返回应答给客户端
125-
if (res.status().code() != 200) {
126-
ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), CharsetUtil.UTF_8);
127-
res.content().writeBytes(buf);
128-
buf.release();
87+
/**
88+
* 唯一的一次http请求,用于创建websocket
89+
*/
90+
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
91+
//要求Upgrade为websocket,过滤掉get/Post
92+
if (!req.decoderResult().isSuccess()
93+
|| (!"websocket".equals(req.headers().get("Upgrade")))) {
94+
//若不是websocket方式,则创建BAD_REQUEST的req,返回给客户端
95+
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(
96+
HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
97+
return;
98+
}
99+
100+
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
101+
"ws://localhost:7094/ws", null, false);
102+
handshaker = wsFactory.newHandshaker(req);
103+
if (handshaker == null) {
104+
WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
105+
} else {
106+
handshaker.handshake(ctx.channel(), req);
107+
}
129108
}
130-
ChannelFuture f = ctx.channel().writeAndFlush(res);
131-
// 如果是非Keep-Alive,关闭连接
132-
if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) {
133-
f.addListener(ChannelFutureListener.CLOSE);
109+
110+
/**
111+
* 拒绝不合法的请求,并返回错误信息
112+
*/
113+
private static void sendHttpResponse(ChannelHandlerContext ctx,
114+
FullHttpRequest req, DefaultFullHttpResponse res) {
115+
// 返回应答给客户端
116+
if (res.status().code() != 200) {
117+
ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), CharsetUtil.UTF_8);
118+
res.content().writeBytes(buf);
119+
buf.release();
120+
}
121+
ChannelFuture f = ctx.channel().writeAndFlush(res);
122+
// 如果是非Keep-Alive,关闭连接
123+
if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) {
124+
f.addListener(ChannelFutureListener.CLOSE);
125+
}
134126
}
135-
}
136127
}

0 commit comments

Comments
 (0)