├── .gitignore
├── ByteBuf.uml
├── ByteBufAllocator.uml
├── README.md
├── pom.xml
└── src
└── main
└── java
├── com
└── lingdu
│ └── idea
│ ├── README.md
│ ├── Test1.java
│ ├── Test10.java
│ ├── Test11.java
│ ├── Test12.java
│ ├── Test13.java
│ ├── Test14.java
│ ├── Test15.java
│ ├── Test16.java
│ ├── Test17.java
│ ├── Test18.java
│ ├── Test19.java
│ ├── Test2.java
│ ├── Test20.java
│ ├── Test21.java
│ ├── Test22.java
│ ├── Test23.java
│ ├── Test24.java
│ ├── Test3.java
│ ├── Test4.java
│ ├── Test5.java
│ ├── Test6.java
│ ├── Test7.java
│ ├── Test8.java
│ └── Test9.java
└── io
└── netty
└── example
└── echo
├── EchoClient.java
├── EchoClientHandler.java
├── EchoServer.java
├── EchoServerHandler.java
├── ThreadSafeCache.java
└── test
├── BizHander.java
├── ByteBufTest.java
├── ChannelInboundHandlerAdapter1.java
├── ChannelInboundHandlerAdapter2.java
├── ChannelInboundHandlerAdapter3.java
├── ChannelInboundHandlerAdapter5.java
├── ChannelInboundHandlerAdapter6.java
├── ChannelInboundHandlerAdapterFileRegion.java
├── ChannelOutboundHandlerAdapter1.java
├── ChannelOutboundHandlerAdapter2.java
├── ChannelOutboundHandlerAdapter3.java
├── FastThreadLocalOldVersionTest.java
├── FastThreadLocalTest.java
├── HashedWheelTimerTest.java
├── JMHTest.java
├── JOLTest.java
├── RecyclerTest.java
├── ServerFileRegion.java
├── ServerT1.java
├── ServerT2.java
├── ThreadLocalHashTest.java
├── ValueNoPaddingTest.java
└── ValuePaddingTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *dependency-reduced-pom.xml
2 | .classpath
3 | .project
4 | .settings/
5 | target/
6 | devenv
7 | *.log*
8 | *.iml
9 | .idea/
10 | *.versionsBackup
11 | !NOTICE-BIN
12 | !LICENSE-BIN
13 | .DS_Store
--------------------------------------------------------------------------------
/ByteBuf.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JAVA
4 | io.netty.buffer.ByteBuf
5 |
6 | io.netty.buffer.PooledUnsafeDirectByteBuf
7 | io.netty.buffer.ByteBuf
8 | io.netty.buffer.UnpooledUnsafeHeapByteBuf
9 | io.netty.buffer.PooledDirectByteBuf
10 | io.netty.buffer.AbstractByteBuf
11 | io.netty.buffer.UnpooledUnsafeDirectByteBuf
12 | io.netty.buffer.PooledByteBuf
13 | io.netty.buffer.ByteBufUtil.ThreadLocalDirectByteBuf
14 | io.netty.buffer.ByteBufUtil.ThreadLocalUnsafeDirectByteBuf
15 | io.netty.buffer.PooledUnsafeHeapByteBuf
16 | io.netty.buffer.PooledHeapByteBuf
17 | io.netty.buffer.UnpooledDirectByteBuf
18 | io.netty.buffer.AbstractReferenceCountedByteBuf
19 | io.netty.buffer.UnpooledHeapByteBuf
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 | All
92 | private
93 |
94 |
95 |
--------------------------------------------------------------------------------
/ByteBufAllocator.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | JAVA
4 | io.netty.buffer.ByteBufAllocator
5 |
6 | io.netty.buffer.UnpooledByteBufAllocator
7 | io.netty.buffer.ByteBufAllocator
8 | io.netty.channel.PreferHeapByteBufAllocator
9 | io.netty.buffer.AbstractByteBufAllocator
10 | io.netty.buffer.PooledByteBufAllocator
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 | All
43 | private
44 |
45 |
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nettydemo
2 | 学习netty。 微信公众号:匠心零度【关注获取更多精彩历史】
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.netty.demo
8 | nettydemo
9 | 1.0-SNAPSHOT
10 |
11 |
12 |
13 |
14 | org.apache.maven.plugins
15 | maven-compiler-plugin
16 |
17 | 1.8
18 | 1.8
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | io.netty
27 | netty-all
28 | 4.1.37.Final
29 |
30 |
31 |
32 | org.openjdk.jol
33 | jol-core
34 | 0.8
35 |
36 |
37 | org.openjdk.jmh
38 | jmh-core
39 | 1.21
40 |
41 |
42 | org.openjdk.jmh
43 | jmh-generator-annprocess
44 | 1.21
45 | provided
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [IntelliJ IDEA 2019.2最新解读:性能更好,体验更优,细节处理更完美!](http://www.jiangxinlingdu.com/idea/2019/07/29/idea-201902.html)
4 |
5 | [idea万能快捷键(alt enter),你不知道的17个实用技巧!!!](http://www.jiangxinlingdu.com/idea/2019/07/19/idea.html)
6 |
7 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test1.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test1 {
7 | public static void main(String[] args) {
8 | //转换为lambda形式
9 | new Thread(new Runnable() {
10 | @Override public void run() {
11 | System.out.println("test");
12 | }
13 | }).start();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test10.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test10 {
7 | public static void main(String[] args) {
8 |
9 | //引入局部变量
10 |
11 | Integer.parseInt("10");
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test11.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | *
6 | * 实现接口
7 | */
8 |
9 | public interface Test11 {
10 | void testa();
11 | }
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test12.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | *
6 | * 实现抽象类
7 | */
8 |
9 | public abstract class Test12 {
10 | abstract void testb();
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test13.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test13 {
7 | public static void main(String[] args) {
8 |
9 | boolean flag = false;
10 |
11 | //修改方法返回值
12 | // flag = test(flag);
13 |
14 |
15 | //生成方法
16 | // testa(flag);
17 |
18 | //方法添加参数,减少参数
19 | int num = 0;
20 | // testb(flag,num);
21 |
22 |
23 | //方法减少参数
24 | // testc(flag);
25 |
26 | }
27 |
28 | private static void testc(boolean flag, int num) {
29 |
30 | }
31 |
32 | private static void testb(boolean flag) {
33 | }
34 |
35 | private static void test(boolean flag) {
36 |
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test14.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test14 {
7 | public static void main(String[] args) {
8 |
9 | //字符串相关操作
10 |
11 |
12 | /**
13 | * 【推荐】 循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。
14 | * 说明:下例中,反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,然后进行
15 | * append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。
16 | *
17 | * 反例:
18 | String str = "start";
19 | for (int i = 0; i < 100; i++) {
20 | str = str + "hello";
21 | }
22 | */
23 |
24 | String str = "start";
25 | for (int i = 0; i < 100; i++) {
26 | str = str + "hello";
27 | }
28 |
29 |
30 | /**
31 | * 1 把str那句话下移
32 | * 万能键 变成StringBuilder语句
33 | * 之后在万能键 变成顺序的语句
34 | *
35 | * 之后再移动 即可
36 | */
37 |
38 | //合并
39 | String testb = "test" + "hello";
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test15.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test15 {
7 | public static void main(String[] args) {
8 |
9 | int a = 10;
10 | int b = 20;
11 |
12 | //, + < 等位置互换
13 | sum(a, b);
14 |
15 | int num = a + b;
16 |
17 | if (100 > num) {
18 |
19 | }
20 |
21 | }
22 |
23 | private static void sum(int a, int b) {
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test16.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test16 {
7 | public static void main(String[] args) {
8 |
9 |
10 | }
11 |
12 | //java访问修饰符的更改操作
13 | private static void sum(int a, int b) {
14 |
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test17.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test17 {
7 | public static void main(String[] args) {
8 |
9 |
10 | }
11 |
12 | //自动生成属性操作
13 | private void sum(int a, int b) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test18.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test18 {
7 | public static void main(String[] args) {
8 | }
9 |
10 | //多个return重构单个return
11 | private String test(int a) {
12 | if (a < 0) {
13 | return "1";
14 | } else if (a == 0) {
15 | return "2";
16 | } else if (a > 100) {
17 | return "3";
18 | } else {
19 | return "4";
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test19.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test19 {
7 |
8 | public static boolean a = true;
9 | public static void main(String[] args) {
10 | test();
11 | System.out.println(a);
12 | }
13 |
14 | //内联方法重构
15 | private static void test() {
16 | if (a) {
17 | return ;
18 | }
19 | doTest();
20 | }
21 |
22 | private static void doTest() {
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test2.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test2 {
7 | /**
8 | * 【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。
9 | * 正例:"test".equals(object);
10 | * 反例:object.equals("test");
11 | */
12 | public static void main(String[] args) {
13 |
14 | String str = null;
15 |
16 | if (str.equals("test")) {
17 |
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test20.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test20 {
7 |
8 | public static boolean a = true;
9 | public static void main(String[] args) {
10 | String str = test();
11 | System.out.println(str);
12 | }
13 |
14 | //Constant conditions & exceptions
15 | private static String test() {
16 | if (a) {
17 | return "1";
18 | }
19 |
20 | if(!a){
21 | return "2";
22 | }
23 |
24 | return "0";
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test21.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test21 {
7 |
8 | public static boolean a = true;
9 | public static void main(String[] args) {
10 | String str = test();
11 | System.out.println(str);
12 | }
13 |
14 | private static String test() {
15 | if (a) {
16 | return "1";
17 | }
18 |
19 | //提示更加智能化了!
20 | //retr
21 | return "2";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test22.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test22 {
7 |
8 | public static boolean a = true;
9 | public static void main(String[] args) {
10 | String str = test();
11 | System.out.println(str);
12 | }
13 |
14 | private static String test() {
15 | for (int i = 0; i < 100; i++) {
16 | System.out.println("abc");
17 | for (int i1 = 0; i1 < 20; i1++) {
18 | System.out.println("cdb");
19 | }
20 | for (int i1 = 0; i1 < 20; i1++) {
21 | System.out.println("cdb");
22 | }
23 | }
24 | return "2";
25 | }
26 |
27 | private static String test2() {
28 | for (int i = 0; i < 100; i++) {
29 | System.out.println("abc");
30 | for (int j1 = 0; j1 < 20; j1++) {
31 | System.out.println("cdb");
32 | }
33 | for (int j3 = 0; j3 < 20; j3++) {
34 | System.out.println("cdb");
35 | }
36 | }
37 | return "2";
38 | }
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test23.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test23 {
7 |
8 | public static void main(String[] args) {
9 | String name = "test";
10 | if ("id".equals(name) || "name".equals(name)) {
11 | System.out.println(name);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test24.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test24 {
7 |
8 | public static void main(String[] args) {
9 | String name = "test";
10 | {if ("id".equals(name) || "name".equals(name)) {
11 | System.out.println("test");
12 | }}
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test3.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test3 {
7 |
8 | //自动导包
9 | //private static SimpleDateFormat simpleDateFormat = new
10 |
11 | public static void main(String[] args) {
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test4.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | import java.text.SimpleDateFormat;
4 |
5 | /**
6 | * @author 匠心零度
7 | */
8 | public class Test4 {
9 |
10 | private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
11 |
12 | public static void main(String[] args) {
13 | String dateTime = "2019-12-31 23:59:59";
14 | for (int i = 0; i < 10; i++) {
15 | new Thread(() -> {
16 | for (int i1 = 0; i1 < 10; i1++) {
17 | //捕获异常
18 | //System.out.println(simpleDateFormat.parse(dateTime));
19 | }
20 | }).start();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test5.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 |
6 | /**
7 | * @author 匠心零度
8 | */
9 | public class Test5 {
10 | //SimpleDateFormat 是线程不安全的类,使用ThreadLocal使得安全
11 |
12 | private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
13 |
14 | public static void main(String[] args) {
15 | String dateTime = "2019-12-31 23:59:59";
16 | for (int i = 0; i < 10; i++) {
17 | new Thread(()->{
18 | for (int i1 = 0; i1 < 10; i1++) {
19 | try {
20 | System.out.println(simpleDateFormat.parse(dateTime));
21 | } catch (ParseException e) {
22 | e.printStackTrace();
23 | }
24 | }
25 | }).start();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test6.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test6 {
7 | public static void main(String[] args) {
8 | //【强制】方法内部单行注释,在被注释语句上方另起一行,使用//注释。
9 |
10 | String str = "test"; //test
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test7.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test7 {
7 | public static void main(String[] args) {
8 | //便捷的json字符串处理
9 | /**
10 | {
11 | "employees": [
12 | {
13 | "firstName": "Bill",
14 | "lastName": "Gates"
15 | },
16 | {
17 | "firstName": "Thomas",
18 | "lastName": "Carter"
19 | }
20 | ]
21 | }
22 |
23 | {"employees":[{"firstName":"Bill","lastName":"Gates"},{"firstName":"Thomas","lastName":"Carter"}]}
24 | */
25 |
26 | String json = "{\"employees\":[{\"firstName\":\"Bill\",\"lastName\":\"Gates\"},{\"firstName\":\"Thomas\",\"lastName\":\"Carter\"}]}";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test8.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test8 {
7 | public static void main(String[] args) {
8 |
9 | //转化为高效运算的二进制
10 |
11 | int num = 128;
12 |
13 | int a = num * 32;
14 | int b = num / 32;
15 |
16 | int aa = num * 32;
17 | int bb = num / 32;
18 |
19 | System.out.println(a == aa);
20 | System.out.println(b == bb);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/lingdu/idea/Test9.java:
--------------------------------------------------------------------------------
1 | package com.lingdu.idea;
2 |
3 | /**
4 | * @author 匠心零度
5 | */
6 | public class Test9 {
7 | public static void main(String[] args) {
8 |
9 | boolean flag = false;
10 | int num;
11 |
12 | //if……else变成简单三目运算
13 |
14 | if (flag) {
15 | num = 6;
16 | } else {
17 | num = 10;
18 | }
19 |
20 |
21 |
22 | flag = test(flag);
23 |
24 | System.out.println(num);
25 | }
26 |
27 | private static boolean test(boolean flag) {
28 | //简化if……else
29 |
30 | if(flag){
31 | return true;
32 | }
33 | return false;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/EchoClient.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package io.netty.example.echo;
17 |
18 | import io.netty.bootstrap.Bootstrap;
19 | import io.netty.channel.ChannelFuture;
20 | import io.netty.channel.ChannelInitializer;
21 | import io.netty.channel.ChannelOption;
22 | import io.netty.channel.ChannelPipeline;
23 | import io.netty.channel.EventLoopGroup;
24 | import io.netty.channel.nio.NioEventLoopGroup;
25 | import io.netty.channel.socket.SocketChannel;
26 | import io.netty.channel.socket.nio.NioSocketChannel;
27 | import io.netty.handler.codec.LineBasedFrameDecoder;
28 | import io.netty.handler.codec.string.StringDecoder;
29 | import io.netty.handler.ssl.SslContext;
30 | import io.netty.handler.ssl.SslContextBuilder;
31 | import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
32 |
33 | /**
34 | * Sends one message when a connection is open and echoes back any received
35 | * data to the server. Simply put, the echo client initiates the ping-pong
36 | * traffic between the echo client and server by sending the first message to
37 | * the server.
38 | */
39 | public final class EchoClient {
40 |
41 | static final String HOST = System.getProperty("host", "127.0.0.1");
42 | static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
43 | static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));
44 |
45 | public static void main(String[] args) throws Exception {
46 |
47 | // Configure the client.
48 | EventLoopGroup group = new NioEventLoopGroup();
49 | try {
50 | Bootstrap b = new Bootstrap();
51 | b.group(group)
52 | .channel(NioSocketChannel.class)
53 | .option(ChannelOption.TCP_NODELAY, true)
54 | .handler(new ChannelInitializer() {
55 | @Override
56 | public void initChannel(SocketChannel ch) throws Exception {
57 | ChannelPipeline p = ch.pipeline();
58 | p.addLast(new LineBasedFrameDecoder(1024)); //很重要哦
59 | p.addLast(new StringDecoder()); //很重要哦
60 | //p.addLast(new LoggingHandler(LogLevel.INFO));
61 | p.addLast(new EchoClientHandler());
62 | }
63 | });
64 |
65 | // Start the client.
66 | ChannelFuture f = b.connect(HOST, PORT).sync();
67 |
68 | // Wait until the connection is closed.
69 | f.channel().closeFuture().sync();
70 | } finally {
71 | // Shut down the event loop to terminate all threads.
72 | group.shutdownGracefully();
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/EchoClientHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package io.netty.example.echo;
17 |
18 | import io.netty.buffer.ByteBuf;
19 | import io.netty.buffer.Unpooled;
20 | import io.netty.channel.ChannelHandlerContext;
21 | import io.netty.channel.ChannelInboundHandlerAdapter;
22 |
23 | /**
24 | * Handler implementation for the echo client. It initiates the ping-pong traffic between the echo client and server by
25 | * sending the first message to the server.
26 | */
27 | public class EchoClientHandler extends ChannelInboundHandlerAdapter {
28 |
29 | private byte[] req;
30 |
31 | /**
32 | * Creates a client-side handler.
33 | */
34 | public EchoClientHandler() {
35 | req = ("零度你好,关注了你的公众号:【匠心零度】。" + System.getProperty("line.separator")).getBytes();
36 | }
37 |
38 | @Override
39 | public void channelActive(ChannelHandlerContext ctx) {
40 | ByteBuf message = null;
41 | for (int i = 0; i < 100; i++) {
42 | message = Unpooled.buffer(req.length);
43 | message.writeBytes(req);
44 | ctx.writeAndFlush(message);
45 | }
46 | }
47 |
48 | @Override
49 | public void channelRead(ChannelHandlerContext ctx, Object msg) {
50 | String body = (String) msg;
51 | System.out.println(body);
52 | }
53 |
54 | @Override
55 | public void channelReadComplete(ChannelHandlerContext ctx) {
56 | ctx.flush();
57 | }
58 |
59 | @Override
60 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
61 | // Close the connection when an exception is raised.
62 | cause.printStackTrace();
63 | ctx.close();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/EchoServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package io.netty.example.echo;
17 |
18 | import io.netty.bootstrap.ServerBootstrap;
19 | import io.netty.channel.ChannelFuture;
20 | import io.netty.channel.ChannelInitializer;
21 | import io.netty.channel.ChannelOption;
22 | import io.netty.channel.ChannelPipeline;
23 | import io.netty.channel.EventLoopGroup;
24 | import io.netty.channel.nio.NioEventLoopGroup;
25 | import io.netty.channel.socket.SocketChannel;
26 | import io.netty.channel.socket.nio.NioServerSocketChannel;
27 | import io.netty.handler.codec.LineBasedFrameDecoder;
28 | import io.netty.handler.codec.string.StringDecoder;
29 | import io.netty.handler.logging.LogLevel;
30 | import io.netty.handler.logging.LoggingHandler;
31 | import io.netty.handler.ssl.SslContext;
32 | import io.netty.handler.ssl.SslContextBuilder;
33 | import io.netty.handler.ssl.util.SelfSignedCertificate;
34 |
35 | /**
36 | * Echoes back any received data from a client.
37 | */
38 | public final class EchoServer {
39 |
40 | static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
41 |
42 | public static void main(String[] args) throws Exception {
43 |
44 | // Configure the server.
45 | EventLoopGroup bossGroup = new NioEventLoopGroup(1);
46 | EventLoopGroup workerGroup = new NioEventLoopGroup();
47 | try {
48 | ServerBootstrap b = new ServerBootstrap();
49 | b.group(bossGroup, workerGroup)
50 | .channel(NioServerSocketChannel.class)
51 | .option(ChannelOption.SO_BACKLOG, 1024)
52 | .handler(new LoggingHandler(LogLevel.INFO))
53 | .childHandler(new ChannelInitializer() {
54 | @Override
55 | public void initChannel(SocketChannel ch) throws Exception {
56 | ChannelPipeline p = ch.pipeline();
57 | p.addLast(new LineBasedFrameDecoder(1024));//很重要哦
58 | p.addLast(new StringDecoder());//很重要哦
59 | //p.addLast(new LoggingHandler(LogLevel.INFO));
60 | p.addLast(new EchoServerHandler());
61 | }
62 | });
63 |
64 | // Start the server.
65 | ChannelFuture f = b.bind(PORT).sync();
66 |
67 | // Wait until the server socket is closed.
68 | f.channel().closeFuture().sync();
69 | } finally {
70 | // Shut down all event loops to terminate all threads.
71 | bossGroup.shutdownGracefully();
72 | workerGroup.shutdownGracefully();
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/EchoServerHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 The Netty Project
3 | *
4 | * The Netty Project licenses this file to you under the Apache License,
5 | * version 2.0 (the "License"); you may not use this file except in compliance
6 | * with the License. You may obtain a copy of the License at:
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations
14 | * under the License.
15 | */
16 | package io.netty.example.echo;
17 |
18 | import io.netty.buffer.ByteBuf;
19 | import io.netty.buffer.Unpooled;
20 | import io.netty.channel.ChannelHandler.Sharable;
21 | import io.netty.channel.ChannelHandlerContext;
22 | import io.netty.channel.ChannelInboundHandlerAdapter;
23 |
24 | /**
25 | * Handler implementation for the echo server.
26 | */
27 | @Sharable
28 | public class EchoServerHandler extends ChannelInboundHandlerAdapter {
29 |
30 | @Override
31 | public void channelRead(ChannelHandlerContext ctx, Object msg) {
32 | String body = (String) msg;
33 | System.out.println(body);
34 | String req = "感谢关注,希望在这里找到你想要的。" + System.getProperty("line.separator");
35 | ByteBuf resp = Unpooled.copiedBuffer(req.getBytes());
36 | ctx.writeAndFlush(resp);
37 | }
38 |
39 | @Override
40 | public void channelReadComplete(ChannelHandlerContext ctx) {
41 | ctx.flush();
42 | }
43 |
44 | @Override
45 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
46 | // Close the connection when an exception is raised.
47 | cause.printStackTrace();
48 | ctx.close();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/ThreadSafeCache.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo;
2 |
3 | public class ThreadSafeCache {
4 | int result;
5 |
6 | public int getResult() {
7 | return result;
8 | }
9 |
10 | public synchronized void setResult(int result) {
11 | this.result = result;
12 | }
13 |
14 | public static void main(String[] args) {
15 | ThreadSafeCache threadSafeCache = new ThreadSafeCache();
16 |
17 | for (int i = 0; i < 8; i++) {
18 | new Thread(() -> {
19 | int x = 0;
20 | while (threadSafeCache.getResult() < 100) {
21 | x++;
22 | }
23 | System.out.println(x);
24 | }).start();
25 | }
26 |
27 | try {
28 | Thread.sleep(1000);
29 | } catch (InterruptedException e) {
30 | e.printStackTrace();
31 | }
32 |
33 | threadSafeCache.setResult(200);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/BizHander.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.SimpleChannelInboundHandler;
5 |
6 |
7 | public class BizHander extends SimpleChannelInboundHandler {
8 |
9 | @Override
10 | protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
11 |
12 | ctx.channel().write("1");
13 | ctx.pipeline().write("2");
14 | super.channelRead(ctx,msg);
15 |
16 | }
17 |
18 |
19 | @Override
20 | public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
21 | System.out.println("handlerAdded");
22 | }
23 |
24 | @Override
25 | public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
26 | System.out.println("channelRegistered");
27 | }
28 |
29 |
30 | @Override
31 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
32 | System.out.println("channelActive");
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ByteBufTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.buffer.ByteBuf;
4 | import io.netty.buffer.ByteBufAllocator;
5 | import io.netty.buffer.PooledByteBufAllocator;
6 | import io.netty.buffer.Unpooled;
7 |
8 | public class ByteBufTest {
9 | public static void main(String[] args) {
10 | ByteBufAllocator alloc = PooledByteBufAllocator.DEFAULT;
11 |
12 | //tiny规格内存分配 会变成大于等于16的整数倍的数:这里254 会规格化为256
13 | ByteBuf byteBuf = alloc.directBuffer(254);
14 |
15 | byteBuf.writeInt(126);
16 | System.out.println(byteBuf.readInt());
17 | //很重要,内存释放
18 | byteBuf.release();
19 |
20 | //走缓存
21 | byteBuf = alloc.directBuffer(256);
22 |
23 | byteBuf.writeInt(126);
24 | System.out.println(byteBuf.readInt());
25 |
26 | // 模拟走另一个分支(继续再chunk上面分配page里面另外的subpage) 所以暂时不释放, 稍后释放,
27 | //byteBuf.release();
28 |
29 | ByteBuf byteBuf0 = alloc.directBuffer(256);
30 |
31 | byteBuf0.writeInt(126);
32 | System.out.println(byteBuf0.readInt());
33 |
34 | //进行释放
35 | byteBuf.release();
36 | byteBuf0.release();
37 |
38 | //small规格内存分配 会变成大于等于2的幂次方的数:这里2*1023 会规格化为2*1024
39 | byteBuf = alloc.directBuffer(2 * 1023);
40 |
41 | byteBuf.writeInt(127);
42 | System.out.println(byteBuf.readInt());
43 | //很重要,内存释放
44 | byteBuf.release();
45 |
46 | //走缓存
47 | byteBuf = alloc.directBuffer(2 * 1024);
48 |
49 | byteBuf.writeInt(127);
50 | System.out.println(byteBuf.readInt());
51 | //很重要,内存释放
52 | byteBuf.release();
53 |
54 | //normal规格内存分配
55 | byteBuf = alloc.directBuffer(8 * 1024);
56 | byteBuf.writeInt(128);
57 | System.out.println(byteBuf.readInt());
58 | //很重要,内存释放
59 | byteBuf.release();
60 |
61 | //不走缓存
62 | byteBuf = alloc.directBuffer(64 * 1024);
63 | byteBuf.writeInt(128);
64 | System.out.println(byteBuf.readInt());
65 | //很重要,内存释放
66 | byteBuf.release();
67 |
68 | ByteBuf byteBuf1 = Unpooled.buffer(10);
69 | byteBuf1.release();
70 |
71 | ByteBuf byteBuf2 = Unpooled.directBuffer(20);
72 | byteBuf2.release();
73 |
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelInboundHandlerAdapter1.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 |
6 |
7 | public class ChannelInboundHandlerAdapter1 extends ChannelInboundHandlerAdapter {
8 | @Override
9 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
10 | System.out.println("ChannelInboundHandlerAdapter1");
11 | super.channelRead(ctx, msg);
12 | }
13 |
14 | @Override
15 | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
16 | super.channelReadComplete(ctx);
17 | }
18 |
19 | @Override
20 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
21 | System.out.println("ChannelInboundHandlerAdapter1 exceptionCaught");
22 | super.exceptionCaught(ctx, cause);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelInboundHandlerAdapter2.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelInboundHandlerAdapter;
5 |
6 |
7 | public class ChannelInboundHandlerAdapter2 extends ChannelInboundHandlerAdapter {
8 | @Override
9 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
10 | System.out.println("ChannelInboundHandlerAdapter2");
11 | super.channelRead(ctx, msg);
12 | }
13 |
14 |
15 | @Override
16 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
17 | System.out.println("ChannelInboundHandlerAdapter2 exceptionCaught");
18 | super.exceptionCaught(ctx, cause);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelInboundHandlerAdapter3.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.*;
4 |
5 |
6 | public class ChannelInboundHandlerAdapter3 extends ChannelInboundHandlerAdapter {
7 | @Override
8 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
9 | System.out.println("ChannelInboundHandlerAdapter3");
10 |
11 |
12 | /* //这段代码 怎么执行都是继续执行,不阻塞 最后,ractor线程里面都是同步的
13 | ChannelFuture future = ctx.channel().writeAndFlush("hello");
14 | future.addListener(new ChannelFutureListener() {
15 | public void operationComplete(ChannelFuture future) throws Exception {
16 | System.out.println("======");
17 | if (future.isSuccess()) {
18 | Thread.sleep(5000);
19 | System.out.println("======isSuccess");
20 | }
21 | }
22 | });
23 |
24 | System.out.println("继续执行,不阻塞");*/
25 |
26 | new Thread(new ThreadTep(ctx.channel())).start();
27 |
28 | super.channelRead(ctx, msg);
29 | }
30 |
31 | @Override
32 | public void channelActive(ChannelHandlerContext ctx) throws Exception {
33 | /* try {
34 | System.out.println(1/0);
35 | } catch (Exception e) {
36 | e.printStackTrace();
37 | ctx.pipeline().fireExceptionCaught(e);
38 | }*/
39 | // ctx.pipeline().fireChannelRead("a");
40 |
41 | }
42 |
43 | @Override
44 | public void channelInactive(ChannelHandlerContext ctx) throws Exception {
45 | super.channelInactive(ctx);
46 | }
47 |
48 | @Override
49 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
50 | System.out.println("ChannelInboundHandlerAdapter3 exceptionCaught");
51 | //如果这么写不就是死循环了嘛 ,传递到下面去了之后又传递过来又执行,反复执行了
52 | //ctx.pipeline().fireExceptionCaught(cause);
53 |
54 | ctx.fireExceptionCaught(cause);
55 | }
56 |
57 |
58 | class ThreadTep implements Runnable{
59 | private Channel channel;
60 |
61 | public ThreadTep() {
62 | }
63 |
64 | public ThreadTep(Channel channel) {
65 | this.channel = channel;
66 | }
67 |
68 | public void run() {
69 | ChannelFuture future = channel.writeAndFlush("hello");
70 | future.addListener(new ChannelFutureListener() {
71 | public void operationComplete(ChannelFuture future) throws Exception {
72 | System.out.println("======");
73 | if (future.isSuccess()) {
74 | Thread.sleep(5000);
75 | System.out.println("======isSuccess");
76 | }
77 | }
78 | });
79 |
80 | System.out.println("继续执行,不阻塞");
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelInboundHandlerAdapter5.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelFuture;
4 | import io.netty.channel.ChannelFutureListener;
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.channel.ChannelInboundHandlerAdapter;
7 |
8 | public class ChannelInboundHandlerAdapter5 extends ChannelInboundHandlerAdapter {
9 | @Override
10 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
11 | System.out.println("ChannelInboundHandlerAdapter5");
12 |
13 | //这段代码 怎么执行都是顺序执行,不阻塞 最后,reactor线程里面都是同步的
14 | ChannelFuture future = ctx.channel().writeAndFlush("hello");
15 | future.addListener(new ChannelFutureListener() {
16 | public void operationComplete(ChannelFuture future) throws Exception {
17 | System.out.println("isDone======");
18 | if (future.isSuccess()) {
19 | Thread.sleep(5000);
20 | System.out.println("======isSuccess");
21 | }
22 | }
23 | });
24 |
25 | System.out.println("继续执行,不阻塞");
26 |
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelInboundHandlerAdapter6.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.Channel;
4 | import io.netty.channel.ChannelFuture;
5 | import io.netty.channel.ChannelFutureListener;
6 | import io.netty.channel.ChannelHandlerContext;
7 | import io.netty.channel.ChannelInboundHandlerAdapter;
8 |
9 | public class ChannelInboundHandlerAdapter6 extends ChannelInboundHandlerAdapter {
10 | @Override
11 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
12 | System.out.println("ChannelInboundHandlerAdapter6");
13 |
14 | new Thread(new ThreadTep(ctx.channel())).start();
15 | }
16 |
17 | class ThreadTep implements Runnable {
18 | private Channel channel;
19 |
20 | public ThreadTep() {
21 | }
22 |
23 | public ThreadTep(Channel channel) {
24 | this.channel = channel;
25 | }
26 |
27 | public void run() {
28 | ChannelFuture future = channel.writeAndFlush("hello5");
29 | future.addListener(new ChannelFutureListener() {
30 | public void operationComplete(ChannelFuture future) throws Exception {
31 | System.out.println("======isDone");
32 | if (future.isSuccess()) {
33 | Thread.sleep(5000);
34 | System.out.println("======isSuccess");
35 | }
36 | }
37 | });
38 |
39 | System.out.println("继续执行,不阻塞");
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelInboundHandlerAdapterFileRegion.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.*;
4 |
5 | import java.io.IOException;
6 | import java.io.RandomAccessFile;
7 |
8 |
9 | public class ChannelInboundHandlerAdapterFileRegion extends ChannelInboundHandlerAdapter {
10 | @Override
11 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
12 | System.out.println("FileRegion");
13 |
14 |
15 | new Thread(new ThreadTep(ctx.channel())).start();
16 |
17 | super.channelRead(ctx, msg);
18 | }
19 |
20 |
21 |
22 | class ThreadTep implements Runnable{
23 | private Channel channel;
24 |
25 | public ThreadTep() {
26 | }
27 |
28 | public ThreadTep(Channel channel) {
29 | this.channel = channel;
30 | }
31 |
32 | public void run() {
33 |
34 |
35 | try {
36 | RandomAccessFile raf = new RandomAccessFile("C:\\Windows\\System32\\drivers\\etc\\HOSTS", "r");
37 | ChannelFuture future = channel.writeAndFlush(new DefaultFileRegion(raf.getChannel(), 0, raf.length()));
38 | future.addListener(new ChannelFutureListener() {
39 | public void operationComplete(ChannelFuture future) throws Exception {
40 | if (future.isSuccess()) {
41 | System.out.println("======isSuccess");
42 | }
43 | }
44 | });
45 | } catch (IOException e) {
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelOutboundHandlerAdapter1.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelOutboundHandlerAdapter;
5 | import io.netty.channel.ChannelPromise;
6 |
7 |
8 | public class ChannelOutboundHandlerAdapter1 extends ChannelOutboundHandlerAdapter {
9 |
10 |
11 | @Override
12 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
13 | System.out.println("ChannelOutboundHandlerAdapter11 ");
14 | super.write(ctx, msg, promise);
15 | }
16 |
17 |
18 | @Override
19 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
20 | System.out.println("ChannelOutboundHandlerAdapter11 exceptionCaught");
21 | super.exceptionCaught(ctx, cause);
22 | }
23 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelOutboundHandlerAdapter2.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelOutboundHandlerAdapter;
5 | import io.netty.channel.ChannelPromise;
6 |
7 |
8 | public class ChannelOutboundHandlerAdapter2 extends ChannelOutboundHandlerAdapter {
9 |
10 |
11 | @Override
12 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
13 | System.out.println("ChannelOutboundHandlerAdapter22 ");
14 | super.write(ctx, msg, promise);
15 | }
16 |
17 | @Override
18 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
19 | System.out.println("ChannelOutboundHandlerAdapter22 exceptionCaught");
20 | super.exceptionCaught(ctx, cause);
21 | }
22 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ChannelOutboundHandlerAdapter3.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.channel.ChannelHandlerContext;
4 | import io.netty.channel.ChannelOutboundHandlerAdapter;
5 | import io.netty.channel.ChannelPromise;
6 |
7 |
8 | public class ChannelOutboundHandlerAdapter3 extends ChannelOutboundHandlerAdapter {
9 |
10 |
11 | @Override
12 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
13 | System.out.println("ChannelOutboundHandlerAdapter33 ");
14 | super.write(ctx, msg, promise);
15 | }
16 |
17 | @Override
18 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
19 | System.out.println("ChannelOutboundHandlerAdapter33 exceptionCaught");
20 | super.exceptionCaught(ctx, cause);
21 | }
22 |
23 | @Override
24 | public void handlerAdded(final ChannelHandlerContext ctx) throws Exception {
25 |
26 | /* ctx.executor().schedule(new Runnable() {
27 | public void run() {
28 | ctx.channel().writeAndFlush("hello").addListener(new ChannelFutureListener() {
29 | public void operationComplete(ChannelFuture future) throws Exception {
30 | System.out.println("======");
31 | if (future.isSuccess()) {
32 | System.out.println("======isSuccess");
33 | }
34 | }
35 | });
36 | }
37 | }, 3, TimeUnit.SECONDS);*/
38 |
39 | super.handlerAdded(ctx);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/FastThreadLocalOldVersionTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | import io.netty.util.concurrent.FastThreadLocal;
5 | import io.netty.util.concurrent.FastThreadLocalThread;
6 |
7 | import java.io.IOException;
8 |
9 | public class FastThreadLocalOldVersionTest {
10 | private static FastThreadLocal fastThreadLocal = new FastThreadLocal();
11 | private static FastThreadLocal fastThreadLocal1 = new FastThreadLocal();
12 | private static FastThreadLocal fastThreadLocal2 = new FastThreadLocal();
13 | private static FastThreadLocal fastThreadLocal3 = new FastThreadLocal();
14 | private static FastThreadLocal fastThreadLocal4 = new FastThreadLocal();
15 | private static FastThreadLocal fastThreadLocal5 = new FastThreadLocal();
16 | private static FastThreadLocal fastThreadLocal6 = new FastThreadLocal();
17 | private static FastThreadLocal fastThreadLocal7 = new FastThreadLocal();
18 | private static FastThreadLocal fastThreadLocal8 = new FastThreadLocal();
19 | private static FastThreadLocal fastThreadLocal9 = new FastThreadLocal();
20 | private static FastThreadLocal fastThreadLocal19 = new FastThreadLocal();
21 | private static FastThreadLocal fastThreadLocal29 = new FastThreadLocal();
22 | private static FastThreadLocal fastThreadLocal28 = new FastThreadLocal();
23 | private static FastThreadLocal fastThreadLocal27 = new FastThreadLocal();
24 | private static FastThreadLocal fastThreadLocal26 = new FastThreadLocal();
25 | private static FastThreadLocal fastThreadLocal25 = new FastThreadLocal();
26 | private static FastThreadLocal fastThreadLocal24 = new FastThreadLocal();
27 | private static FastThreadLocal fastThreadLocal23 = new FastThreadLocal();
28 | private static FastThreadLocal fastThreadLocal22 = new FastThreadLocal();
29 | private static FastThreadLocal fastThreadLocal21 = new FastThreadLocal();
30 | private static FastThreadLocal fastThreadLocal20 = new FastThreadLocal();
31 | private static FastThreadLocal fastThreadLocal39 = new FastThreadLocal();
32 | private static FastThreadLocal fastThreadLocal79 = new FastThreadLocal();
33 | private static FastThreadLocal fastThreadLocal99 = new FastThreadLocal();
34 |
35 | public static void main(String[] args) throws IOException {
36 |
37 | //if (thread instanceof FastThreadLocalThread) 所以 这里是FastThreadLocalThread而不是普通线程
38 | new FastThreadLocalThread(new Runnable() {
39 | @Override
40 | public void run() {
41 | for (int i = 0; i < 100; i++) {
42 | fastThreadLocal99.set(i);
43 | System.out.println(Thread.currentThread().getName() + "====" + fastThreadLocal99.get());
44 | try {
45 | Thread.sleep(2000);
46 | } catch (InterruptedException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 | }
51 | }, "fastThreadLocal1").start();
52 |
53 |
54 | new FastThreadLocalThread(new Runnable() {
55 | @Override
56 | public void run() {
57 | for (int i = 0; i < 100; i++) {
58 | System.out.println(Thread.currentThread().getName() + "====" + fastThreadLocal99.get());
59 | try {
60 | Thread.sleep(2000);
61 | } catch (InterruptedException e) {
62 | e.printStackTrace();
63 | }
64 | }
65 | }
66 | }, "fastThreadLocal2").start();
67 |
68 |
69 | //老版本有registerCleaner
70 |
71 | /**
72 | * // Fast path for cleaners
73 | * if (c != null) {
74 | * c.clean();
75 | * return true;
76 | * }
77 | *
78 | * ReferenceQueue super Object> q = r.queue;
79 | * if (q != ReferenceQueue.NULL) q.enqueue(r);
80 | * return true;
81 | */
82 | //为了查看引用怎么运行的 Reference Handler,如果pending有值
83 | // 情况1:如果是堆外内存申请时的Cleaner对象,只会执行它的clean方法,并不会放到queue中,之后return了。
84 | //情况2:ReferenceQueue不是默认,就是设置过的,就会调用enqueue存入queue
85 | System.gc();
86 | System.in.read();
87 | }
88 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/FastThreadLocalTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | import io.netty.util.concurrent.FastThreadLocal;
5 | import io.netty.util.concurrent.FastThreadLocalThread;
6 |
7 | public class FastThreadLocalTest {
8 | private static FastThreadLocal fastThreadLocal = new FastThreadLocal<>();
9 |
10 | public static void main(String[] args) {
11 |
12 | //if (thread instanceof FastThreadLocalThread) 使用FastThreadLocalThread更优,普通线程也可以
13 | new FastThreadLocalThread(() -> {
14 | for (int i = 0; i < 100; i++) {
15 | fastThreadLocal.set(i);
16 | System.out.println(Thread.currentThread().getName() + "====" + fastThreadLocal.get());
17 | try {
18 | Thread.sleep(200);
19 | } catch (InterruptedException e) {
20 | e.printStackTrace();
21 | }
22 | }
23 | }, "fastThreadLocal1").start();
24 |
25 |
26 | new FastThreadLocalThread(() -> {
27 | for (int i = 0; i < 100; i++) {
28 | System.out.println(Thread.currentThread().getName() + "====" + fastThreadLocal.get());
29 | try {
30 | Thread.sleep(200);
31 | } catch (InterruptedException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 | }, "fastThreadLocal2").start();
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/HashedWheelTimerTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | import io.netty.util.HashedWheelTimer;
5 | import io.netty.util.Timeout;
6 | import io.netty.util.Timer;
7 | import io.netty.util.TimerTask;
8 |
9 | import java.time.LocalDateTime;
10 | import java.util.concurrent.Executors;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | public class HashedWheelTimerTest {
14 |
15 | public static void main(String[] argv) {
16 |
17 | // tickDuration和unit 每格的时间间隔 多久时钟移动一格
18 | //ticksPerWheel 一圈下来有几格 如果传入的不是2的N次方,则会调整为大于等于该参数的第一个2的N次方,好处是可以优化hash值的计算 时钟一共有多少格
19 | //类比时钟 秒钟 1秒走一格 一共60格 分钟 1分走一格 一共60格 时钟 1小时走一格 一共12格 通过时钟层级就可以表示很多很大的时间刻度了。
20 | final Timer timer = new HashedWheelTimer(Executors.defaultThreadFactory(), 5, TimeUnit.SECONDS, 2);
21 |
22 | timer.newTimeout(new TimerTask() {
23 | @Override
24 | public void run(Timeout timeout) throws Exception {
25 | System.out.println("task 1 will run per 5 seconds ");
26 | //结束时候再次注册
27 | timer.newTimeout(this, 5, TimeUnit.SECONDS);
28 | }
29 | }, 5, TimeUnit.SECONDS);
30 |
31 |
32 | timer.newTimeout(new TimerTask() {
33 | @Override
34 | public void run(Timeout timeout) throws Exception {
35 | System.out.println("task 2 will run per 100 seconds="+LocalDateTime.now());
36 | //结束时候再注册
37 | timer.newTimeout(this, 100, TimeUnit.SECONDS);
38 | }
39 | }, 100, TimeUnit.SECONDS);
40 |
41 |
42 | //该任务仅仅运行一次
43 | timer.newTimeout(timeout -> System.out.println("task 3 run only once ! "), 15, TimeUnit.SECONDS);
44 |
45 | }
46 |
47 |
48 |
49 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/JMHTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | import org.openjdk.jmh.annotations.*;
5 | import org.openjdk.jmh.runner.Runner;
6 | import org.openjdk.jmh.runner.RunnerException;
7 | import org.openjdk.jmh.runner.options.Options;
8 | import org.openjdk.jmh.runner.options.OptionsBuilder;
9 |
10 | import java.util.ArrayList;
11 | import java.util.LinkedList;
12 | import java.util.List;
13 | import java.util.concurrent.TimeUnit;
14 |
15 |
16 | //Mode.Throughput 吞吐量纬度 例如“1秒内可以执行多少次调用”,单位是操作数/时间 越大性能越好。
17 | // Mode.AverageTime 平均时间 例如“每次调用平均耗时xxx毫秒”,单位是时间/操作数 越小性能越好。
18 | // Mode.SampleTime 抽样检测 例如“99%的调用在xxx毫秒以内,99.99%的调用在xxx毫秒以内”
19 | // Mode.SingleShotTime 检测一次调用
20 | // Mode.All 运用所有的检测模式 在方法级别指定@BenchmarkMode的时候可以指定多个纬度,
21 | // 例如: @BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime}),代表同时在多个纬度对目标方法进行测量。
22 | @BenchmarkMode(Mode.Throughput) // 吞吐量
23 |
24 | @OutputTimeUnit(TimeUnit.MILLISECONDS) // 结果所使用的时间单位
25 |
26 | //Scope.Thread:默认的 State,每个测试线程分配一个实例; 不存在线程安全问题
27 | // Scope.Benchmark:所有测试线程共享一个实例,用于测试有状态实例在多线程共享下的性能 也可以测试线程安全问题;
28 | // Scope.Group:每个线程组共享一个实例;
29 | @State(Scope.Thread) // 每个测试线程分配一个实例
30 |
31 | //测试线程的数量,可以配置在方法或者类上,代表执行测试的线程数量。
32 | @Threads(1)
33 |
34 | @Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx2G"}) // Fork进行的数目,2表示用两个进程来进行测试,以及jvm参数
35 |
36 | //iterations:预热的次数。 time:每次预热的时间。 timeUnit:时间单位,默认是s。 batchSize:批处理大小,每次操作调用几次方法。
37 | // 先预热5轮 每隔1秒进行一次预热操作
38 | @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
39 |
40 | @Measurement(iterations = 10) // 进行10轮测试 配置的选项和warmup一样。
41 |
42 | public class JMHTest {
43 | @Param({"10", "40", "70", "100"}) // 定义四个参数,之后会分别对这四个参数进行测试
44 | private int n;
45 |
46 | private List array;
47 | private List list;
48 |
49 | //Level.Trial 只会在个基础测试的前后执行。包括Warmup和Measurement阶段,一共只会执行一次。
50 | // Level.Iteration 每次执行基准测试方法的时候都会执行,如果Warmup和Measurement都配置了2次执行的话,那么@Setup和@TearDown配置的方法的执行次数就4次。
51 | // Level.Invocation 每个方法执行的前后执行(一般不推荐这么用)
52 |
53 | @Setup(Level.Trial) // 初始化方法,在全部Benchmark运行之前进行
54 | public void init() {
55 | array = new ArrayList<>(0);
56 | list = new LinkedList<>();
57 | for (int i = 0; i < n; i++) {
58 | array.add(i);
59 | list.add(i);
60 | }
61 | }
62 |
63 | @Benchmark
64 | public void arrayTraverse() {
65 | for (int i = 0; i < n; i++) {
66 | array.get(i);
67 | }
68 | }
69 |
70 | @Benchmark
71 | public void listTraverse() {
72 | for (int i = 0; i < n; i++) {
73 | list.get(i);
74 | }
75 | }
76 |
77 |
78 | @TearDown(Level.Trial) // 结束方法,在全部Benchmark运行之后进行
79 | public void arrayRemove() {
80 | for (int i = 0; i < n; i++) {
81 | array.remove(0);
82 | list.remove(0);
83 | }
84 | }
85 |
86 | public static void main(String[] args) throws RunnerException {
87 |
88 | Options opt = new OptionsBuilder()
89 | .include(JMHTest.class.getSimpleName())
90 | .build();
91 |
92 | new Runner(opt).run();
93 | }
94 |
95 | }
96 |
97 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/JOLTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | import io.netty.util.internal.InternalThreadLocalMap;
5 | import org.openjdk.jol.info.ClassLayout;
6 |
7 | import static java.lang.System.out;
8 |
9 | public class JOLTest {
10 | public static void main(String[] args) throws Exception {
11 | out.println(ClassLayout.parseClass(InternalThreadLocalMap.class).toPrintable());
12 | out.println(ClassLayout.parseClass(A.class).toPrintable());
13 | }
14 |
15 |
16 | class A{
17 | public volatile long value = 0L;
18 | public long p1, p2, p3, p4, p5; // comment out
19 |
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/RecyclerTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | import io.netty.util.Recycler;
5 | import io.netty.util.concurrent.FastThreadLocalThread;
6 |
7 | public class RecyclerTest {
8 |
9 |
10 | private static Recycler recycler = new Recycler() {
11 |
12 | @Override
13 | protected User newObject(Handle handle) {
14 | return new User("零度", handle);
15 | }
16 | };
17 |
18 |
19 | public static void main(String[] args) {
20 |
21 | try {
22 | differentThreadRecycler();
23 | } catch (InterruptedException e) {
24 | }
25 |
26 | sameThreadRecycler();
27 | }
28 |
29 | private static void sameThreadRecycler() {
30 | User user = recycler.get();
31 | System.out.println(user.getName());
32 |
33 | user.setName("匠心零度");
34 |
35 | //当前回收的线程和Stack所属的线程一致
36 | user.recycle();
37 |
38 |
39 | new FastThreadLocalThread(() -> {
40 |
41 | User user2 = recycler.get();
42 | System.out.println(user2.getName());
43 |
44 | user2.setName("匠心-零度");
45 |
46 | //当前回收的线程和Stack所属的线程一致
47 | user2.recycle();
48 |
49 | user2 = recycler.get();
50 | System.out.println(Thread.currentThread().getName() + ":" + user2.getName());
51 |
52 |
53 | }).start();
54 |
55 | user = recycler.get();
56 | System.out.println(Thread.currentThread().getName() + ":" + user.getName());
57 | }
58 |
59 |
60 | public static void differentThreadRecycler() throws InterruptedException {
61 | //Stack属于main线程
62 | User user1 = recycler.get();
63 | System.out.println(user1.getName());
64 | user1.setName("hello,java");
65 |
66 | Thread thread = new Thread(() -> {
67 | System.out.println(user1.getName());
68 | user1.setName("hello,netty");
69 | //当前回收的线程和Stack所属的线程不一致 需要添加到WeakOrderQueue中
70 | user1.recycle();
71 | });
72 |
73 | thread.start();
74 | thread.join();
75 |
76 | // 将其他线程回收的对象重新加入到Stack中进行获取
77 | User user2 = recycler.get();
78 | System.out.println(user2.getName());
79 | //等于true 表示是同一对象
80 | System.out.println(user1 == user2);
81 | }
82 |
83 | }
84 |
85 | class User {
86 | private String name;
87 | private Recycler.Handle handle;
88 |
89 | public User() {
90 | }
91 |
92 | public User(String name, Recycler.Handle handle) {
93 | this.name = name;
94 | this.handle = handle;
95 | }
96 |
97 | public User(Recycler.Handle handle) {
98 | this.handle = handle;
99 | }
100 |
101 | public String getName() {
102 | return name;
103 | }
104 |
105 | public void setName(String name) {
106 | this.name = name;
107 | }
108 |
109 | public void recycle() {
110 | this.handle.recycle(this);
111 | }
112 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ServerFileRegion.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.channel.*;
5 | import io.netty.channel.nio.NioEventLoopGroup;
6 | import io.netty.channel.socket.SocketChannel;
7 | import io.netty.channel.socket.nio.NioServerSocketChannel;
8 |
9 |
10 | public class ServerFileRegion {
11 | public static void main(String[] args) {
12 |
13 | EventLoopGroup boss = new NioEventLoopGroup(1);
14 | EventLoopGroup woker = new NioEventLoopGroup();
15 |
16 | try {
17 | ServerBootstrap serverBootstrap = new ServerBootstrap();
18 | serverBootstrap.channel(NioServerSocketChannel.class)
19 | .group(boss,woker)
20 | .option(ChannelOption.SO_BACKLOG,1024)
21 | .childOption(ChannelOption.SO_RCVBUF,5*1024)
22 | .childOption(ChannelOption.SO_SNDBUF,5*1024)
23 | .childHandler(new ChannelInitializer() {
24 | @Override
25 | protected void initChannel(SocketChannel ch) throws Exception {
26 | ChannelPipeline pipeline = ch.pipeline();
27 | pipeline.addLast(new ChannelInboundHandlerAdapterFileRegion());
28 | }
29 | });
30 |
31 |
32 | ChannelFuture future = serverBootstrap.bind(8888).sync();
33 |
34 | future.channel().closeFuture().sync();
35 | } catch (InterruptedException e) {
36 | e.printStackTrace();
37 | }finally {
38 | boss.shutdownGracefully();
39 | woker.shutdownGracefully();
40 | }
41 |
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ServerT1.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.channel.*;
5 | import io.netty.channel.nio.NioEventLoopGroup;
6 | import io.netty.channel.socket.SocketChannel;
7 | import io.netty.channel.socket.nio.NioServerSocketChannel;
8 | import io.netty.handler.codec.string.StringDecoder;
9 | import io.netty.handler.codec.string.StringEncoder;
10 |
11 |
12 | public class ServerT1 {
13 | public static void main(String[] args) {
14 |
15 | EventLoopGroup boss = new NioEventLoopGroup(1);
16 | EventLoopGroup woker = new NioEventLoopGroup();
17 |
18 | try {
19 | ServerBootstrap serverBootstrap = new ServerBootstrap();
20 | serverBootstrap.channel(NioServerSocketChannel.class)
21 | .group(boss,woker)
22 | .option(ChannelOption.SO_BACKLOG,1024)
23 | .childOption(ChannelOption.SO_RCVBUF,5*1024)
24 | .childOption(ChannelOption.SO_SNDBUF,5*1024)
25 | // .handler(new BizHander())
26 | .childHandler(new ChannelInitializer() {
27 | @Override
28 | protected void initChannel(SocketChannel ch) throws Exception {
29 | ChannelPipeline pipeline = ch.pipeline();
30 | pipeline.addLast(new StringDecoder());
31 | pipeline.addLast(new StringEncoder());
32 | // pipeline.addLast(new BizHander());
33 | pipeline.addLast(new ChannelInboundHandlerAdapter1());
34 | pipeline.addLast(new ChannelInboundHandlerAdapter2());
35 | pipeline.addLast(new ChannelInboundHandlerAdapter3());
36 | pipeline.addLast(new ChannelOutboundHandlerAdapter1());
37 | pipeline.addLast(new ChannelOutboundHandlerAdapter2());
38 | pipeline.addLast(new ChannelOutboundHandlerAdapter3());
39 | }
40 | });
41 |
42 |
43 | ChannelFuture future = serverBootstrap.bind(8888).sync();
44 |
45 | future.channel().closeFuture().sync();
46 | } catch (InterruptedException e) {
47 | e.printStackTrace();
48 | }finally {
49 | boss.shutdownGracefully();
50 | woker.shutdownGracefully();
51 | }
52 |
53 | }
54 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ServerT2.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import io.netty.bootstrap.ServerBootstrap;
4 | import io.netty.channel.ChannelFuture;
5 | import io.netty.channel.ChannelInitializer;
6 | import io.netty.channel.ChannelOption;
7 | import io.netty.channel.ChannelPipeline;
8 | import io.netty.channel.EventLoopGroup;
9 | import io.netty.channel.nio.NioEventLoopGroup;
10 | import io.netty.channel.socket.SocketChannel;
11 | import io.netty.channel.socket.nio.NioServerSocketChannel;
12 | import io.netty.handler.codec.string.StringDecoder;
13 | import io.netty.handler.codec.string.StringEncoder;
14 |
15 | public class ServerT2 {
16 | public static void main(String[] args) {
17 |
18 | EventLoopGroup boss = new NioEventLoopGroup(1);
19 | EventLoopGroup woker = new NioEventLoopGroup();
20 |
21 | try {
22 | ServerBootstrap serverBootstrap = new ServerBootstrap();
23 | serverBootstrap.channel(NioServerSocketChannel.class)
24 | .group(boss,woker)
25 | .option(ChannelOption.SO_BACKLOG,1024)
26 | .childOption(ChannelOption.SO_RCVBUF,5*1024)
27 | .childOption(ChannelOption.SO_SNDBUF,5*1024)
28 | .childHandler(new ChannelInitializer() {
29 | @Override
30 | protected void initChannel(SocketChannel ch) throws Exception {
31 | ChannelPipeline pipeline = ch.pipeline();
32 | pipeline.addLast(new StringDecoder());
33 | pipeline.addLast(new StringEncoder());
34 | //pipeline.addLast(new ChannelInboundHandlerAdapter5());
35 | pipeline.addLast(new ChannelInboundHandlerAdapter6());
36 | }
37 | });
38 |
39 |
40 | ChannelFuture future = serverBootstrap.bind(8888).sync();
41 |
42 | future.channel().closeFuture().sync();
43 | } catch (InterruptedException e) {
44 | e.printStackTrace();
45 | }finally {
46 | boss.shutdownGracefully();
47 | woker.shutdownGracefully();
48 | }
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ThreadLocalHashTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 | import java.util.concurrent.atomic.AtomicInteger;
6 |
7 | public class ThreadLocalHashTest {
8 |
9 | public static void main(String[] args) {
10 |
11 | int[] array = {16,16<<1,16<<2,16<<3,16<<4,16<<6,16<<7,16<<8};
12 |
13 | for (int i = 0; i < array.length; i++) {
14 | int num = array[i];
15 | Set set = new HashSet<>(num);
16 | System.out.println(num);
17 | int threshold = setThreshold(num);
18 | for (int j = 0; j < threshold; j++) {
19 | int data = nextHashCode() & (num - 1);
20 | set.add(data);
21 | }
22 | System.out.println(set.size()==threshold);
23 | }
24 |
25 | }
26 |
27 | private static int setThreshold(int len) {
28 | return len * 2 / 3;
29 | }
30 |
31 |
32 | private static AtomicInteger nextHashCode =
33 | new AtomicInteger();
34 |
35 | private static final int HASH_INCREMENT = 0x61c88647;
36 |
37 | /**
38 | * Returns the next hash code.
39 | */
40 | private static int nextHashCode() {
41 | return nextHashCode.getAndAdd(HASH_INCREMENT);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ValueNoPaddingTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | public class ValueNoPaddingTest implements Runnable {
5 | public final static long ITERATIONS = 500L * 1000L * 100L;
6 | private int arrayIndex = 0;
7 |
8 | private static ValueNoPadding[] longs;
9 |
10 | public ValueNoPaddingTest(final int arrayIndex) {
11 | this.arrayIndex = arrayIndex;
12 | }
13 |
14 | public static void main(final String[] args) throws Exception {
15 | for (int i = 1; i < 10; i++) {
16 | System.gc();
17 | final long start = System.currentTimeMillis();
18 | runTest(i);
19 | System.out.println("Thread num " + i + " duration = " + (System.currentTimeMillis() - start));
20 | }
21 |
22 | }
23 |
24 | private static void runTest(int NUM_THREADS) throws InterruptedException {
25 | Thread[] threads = new Thread[NUM_THREADS];
26 | longs = new ValueNoPadding[NUM_THREADS];
27 | for (int i = 0; i < longs.length; i++) {
28 | longs[i] = new ValueNoPadding();
29 | }
30 | for (int i = 0; i < threads.length; i++) {
31 | threads[i] = new Thread(new ValueNoPaddingTest(i));
32 | }
33 |
34 | for (Thread t : threads) {
35 | t.start();
36 | }
37 |
38 | for (Thread t : threads) {
39 | t.join();
40 | }
41 | }
42 |
43 | public void run() {
44 | long i = ITERATIONS + 1;
45 | while (0 != --i) {
46 | longs[arrayIndex].value = 0L;
47 | }
48 | }
49 |
50 | public final static class ValuePadding {
51 | protected long p1, p2, p3, p4, p5, p6, p7;
52 | protected volatile long value = 0L;
53 | protected long p9, p10, p11, p12, p13, p14;
54 | protected long p15;
55 | }
56 |
57 | public final static class ValueNoPadding {
58 | // protected long p1, p2, p3, p4, p5, p6, p7;
59 | protected volatile long value = 0L;
60 | // protected long p9, p10, p11, p12, p13, p14, p15;
61 | }
62 | }
--------------------------------------------------------------------------------
/src/main/java/io/netty/example/echo/test/ValuePaddingTest.java:
--------------------------------------------------------------------------------
1 | package io.netty.example.echo.test;
2 |
3 |
4 | public class ValuePaddingTest implements Runnable {
5 | public final static long ITERATIONS = 500L * 1000L * 100L;
6 | private int arrayIndex = 0;
7 |
8 | private static ValuePadding[] longs;
9 |
10 | public ValuePaddingTest(final int arrayIndex) {
11 | this.arrayIndex = arrayIndex;
12 | }
13 |
14 | public static void main(final String[] args) throws Exception {
15 | for (int i = 1; i < 10; i++) {
16 | System.gc();
17 | final long start = System.currentTimeMillis();
18 | runTest(i);
19 | System.out.println("Thread num " + i + " duration = " + (System.currentTimeMillis() - start));
20 | }
21 |
22 | }
23 |
24 | private static void runTest(int NUM_THREADS) throws InterruptedException {
25 | Thread[] threads = new Thread[NUM_THREADS];
26 | longs = new ValuePadding[NUM_THREADS];
27 | for (int i = 0; i < longs.length; i++) {
28 | longs[i] = new ValuePadding();
29 | }
30 | for (int i = 0; i < threads.length; i++) {
31 | threads[i] = new Thread(new ValuePaddingTest(i));
32 | }
33 |
34 | for (Thread t : threads) {
35 | t.start();
36 | }
37 |
38 | for (Thread t : threads) {
39 | t.join();
40 | }
41 | }
42 |
43 | public void run() {
44 | long i = ITERATIONS + 1;
45 | while (0 != --i) {
46 | longs[arrayIndex].value = 0L;
47 | }
48 | }
49 |
50 | public final static class ValuePadding {
51 | protected long p1, p2, p3, p4, p5, p6, p7;
52 | protected volatile long value = 0L;
53 | protected long p9, p10, p11, p12, p13, p14;
54 | protected long p15;
55 | }
56 |
57 | public final static class ValueNoPadding {
58 | // protected long p1, p2, p3, p4, p5, p6, p7;
59 | protected volatile long value = 0L;
60 | // protected long p9, p10, p11, p12, p13, p14, p15;
61 | }
62 | }
--------------------------------------------------------------------------------