├── .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 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 | } --------------------------------------------------------------------------------