diff --git a/.gitignore b/.gitignore index 8f76020..2864663 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ out/ # Others bin/ -.myeclipse \ No newline at end of file +.myeclipse +.hprof \ No newline at end of file diff --git a/README.md b/README.md index bc9c13f..1c21ea6 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,32 @@ -# 我的java学习笔记 +# 我的 Java 学习笔记 -笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解java基础语法,想进一步深入学习的人 +旨在打造在线最佳的 Java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 Java 基础语法,想进一步深入学习的人 -含**博客讲解**和**源码实例**,采用maven构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 +含**博客讲解**和**源码实例**,采用 maven 构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 -**如果觉得不错,请先在这个仓库上点个star吧**,这也是对我的肯定和鼓励,谢谢了。 +**如果觉得不错,请先在这个仓库上点个 star 吧**,这也是对我的肯定和鼓励,谢谢了。 -不定时进行调整和补充,需要关注更新的请 Watch、Star、Fork +不定时进行调整和补充,需要关注更新的请 watch、star、fork ----- # 仓库目录 -- [blogs](/blogs):博客文档 -- [java-base](/java-base):java基础巩固模块的java源码 -- [java-multithread](/java-multithread):多线程模块的java源码 +**点击相应的模块能看到每个目录的说明文档** +- [blogs](/blogs):博客文档 +- [java-base](/java-base):Java 基础巩固模块的 Java 源码 +- [java-multithread](/java-multithread):多线程模块的 Java 源码 +- [java-container](/java-container):容器类模块的 Java 源码 +- [java-io](/java-io):IO 模块的 Java 源码 +- [java-jvm](/java-jvm): JVM 模块的 Java 源码 +- [java8](/java8): Java 8 模块的源码 # 博客文档 -如果你只是单纯要阅读的话,建议移步CSDN或者oschina上观看,访问速度快很多: +如果你只是单纯要阅读的话,建议移步 CSDN 或者 oschina 上观看,访问速度快很多: >* CSDN:[我的java&javaweb学习笔记(汇总)](http://blog.csdn.net/h3243212/article/details/50659471) >* oschina:[我的java&javaweb学习笔记(汇总)](http://my.oschina.net/brianway/blog/614355) @@ -29,7 +34,7 @@ **博客目录** -- [javase](/blogs/javase) +- [Java SE](/blogs/javase) - [java基础巩固笔记(1)-反射.md](/blogs/javase/java基础巩固笔记(1)-反射.md) - [java基础巩固笔记(2)-泛型.md](/blogs/javase/java基础巩固笔记(2)-泛型.md) - [java基础巩固笔记(3)-类加载器.md](/blogs/javase/java基础巩固笔记(3)-类加载器.md) @@ -39,7 +44,7 @@ - [java基础巩固笔记(5)-多线程之共享数据.md](/blogs/javase/java基础巩固笔记(5)-多线程之共享数据.md) - [java基础巩固笔记(5)-多线程之线程并发库.md](/blogs/javase/java基础巩固笔记(5)-多线程之线程并发库.md) - [java基础巩固笔记(6)-注解.md](/blogs/javase/java基础巩固笔记(6)-注解.md) -- [javaweb](/blogs/javaweb) +- [Java Web](/blogs/javaweb) - [javaweb入门笔记(1)-Tomcat.md](/blogs/javaweb/javaweb入门笔记(1)-Tomcat.md) - [javaweb入门笔记(2)-http入门.md](/blogs/javaweb/javaweb入门笔记(2)-http入门.md) - [javaweb入门笔记(3)-Servlet.md](/blogs/javaweb/javaweb入门笔记(3)-Servlet.md) @@ -47,30 +52,40 @@ - [javaweb入门笔记(5)-cookie和session.md](/blogs/javaweb/javaweb入门笔记(5)-cookie和session.md) - [javaweb入门笔记(6)-JSP技术.md](/blogs/javaweb/javaweb入门笔记(6)-JSP技术.md) - ------ +----- + + +## 赞助 + +如果您觉得该项目对您有帮助,请扫描下方二维码对我进行鼓励,以便我更好的维护和更新,谢谢支持! + +![支付宝](https://brianway.github.io/img/alipay_small.png) +![微信](https://brianway.github.io/img/wechatpay_small.png) # TODO 计划将这个仓库进行重构,逐步扩充并实现下面的功能。 -* [x] 整理成maven的结构,使用聚合和继承特性(2016.4.12完成) -* [ ] 原有的javase部分代码重构为java-base模块,并逐步上传代码 -* [ ] 多线程部分使用java-multithread模块(进行中) -* [ ] 集合类部分使用模块java-collection -* [ ] IO部分使用模块java-io +* [x] 整理成 maven 的结构,使用聚合和继承特性(2016.4.12 完成) +* [ ] 原有的 Java SE 部分代码重构为 java-base 模块,并逐步上传代码 +* [x] 多线程部分使用 java-multithread 模块(2016.4.17 完成雏形) +* [ ] 容器类部分使用模块 java-container +* [ ] IO 部分使用模块 java-io +* [x] Java 虚拟机相关部分使用模块 java-jvm(2017.3.20 完成雏形) +* [x] Java 8 新特性使用模块 java8(2017.3.29 完成) - ----- # 联系作者 - [Brian's Personal Website](http://brianway.github.io/) -- [oschina](http://my.oschina.net/brianway) - [CSDN](http://blog.csdn.net/h3243212/) +- [oschina](http://my.oschina.net/brianway) + +Email: weichuyang@163.com ----- diff --git "a/blogs/img/javaSE_\344\273\243\347\220\206\346\236\266\346\236\204\345\233\276.png" "b/blogs/img/javaSE_\344\273\243\347\220\206\346\236\266\346\236\204\345\233\276.png" new file mode 100644 index 0000000..ae378bb Binary files /dev/null and "b/blogs/img/javaSE_\344\273\243\347\220\206\346\236\266\346\236\204\345\233\276.png" differ diff --git "a/blogs/img/javaSE_\345\212\250\346\200\201\344\273\243\347\220\206\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206\345\233\276.jpg" "b/blogs/img/javaSE_\345\212\250\346\200\201\344\273\243\347\220\206\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206\345\233\276.jpg" new file mode 100644 index 0000000..7b2819d Binary files /dev/null and "b/blogs/img/javaSE_\345\212\250\346\200\201\344\273\243\347\220\206\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206\345\233\276.jpg" differ diff --git "a/blogs/img/javaSE_\346\263\233\345\236\213\350\260\203\350\257\225\346\210\252\345\233\276-1.png" "b/blogs/img/javaSE_\346\263\233\345\236\213\350\260\203\350\257\225\346\210\252\345\233\276-1.png" new file mode 100644 index 0000000..365eb5f Binary files /dev/null and "b/blogs/img/javaSE_\346\263\233\345\236\213\350\260\203\350\257\225\346\210\252\345\233\276-1.png" differ diff --git "a/blogs/img/javaSE_\347\261\273\345\212\240\350\275\275\345\231\250\347\273\223\346\236\204\345\233\276.png" "b/blogs/img/javaSE_\347\261\273\345\212\240\350\275\275\345\231\250\347\273\223\346\236\204\345\233\276.png" new file mode 100644 index 0000000..5953249 Binary files /dev/null and "b/blogs/img/javaSE_\347\261\273\345\212\240\350\275\275\345\231\250\347\273\223\346\236\204\345\233\276.png" differ diff --git a/blogs/img/javaweb_HttpResponseStatus.png b/blogs/img/javaweb_HttpResponseStatus.png new file mode 100644 index 0000000..d9e83d2 Binary files /dev/null and b/blogs/img/javaweb_HttpResponseStatus.png differ diff --git a/blogs/img/javaweb_servlet-lifecycle.png b/blogs/img/javaweb_servlet-lifecycle.png new file mode 100644 index 0000000..ba13f14 Binary files /dev/null and b/blogs/img/javaweb_servlet-lifecycle.png differ diff --git "a/blogs/img/javaweb_servlet-url\345\214\271\351\205\215.png" "b/blogs/img/javaweb_servlet-url\345\214\271\351\205\215.png" new file mode 100644 index 0000000..c561a3b Binary files /dev/null and "b/blogs/img/javaweb_servlet-url\345\214\271\351\205\215.png" differ diff --git "a/blogs/img/javaweb_tomcat\344\275\223\347\263\273\347\273\223\346\236\204.png" "b/blogs/img/javaweb_tomcat\344\275\223\347\263\273\347\273\223\346\236\204.png" new file mode 100644 index 0000000..fd0037e Binary files /dev/null and "b/blogs/img/javaweb_tomcat\344\275\223\347\263\273\347\273\223\346\236\204.png" differ diff --git "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(1)-\345\217\215\345\260\204.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(1)-\345\217\215\345\260\204.md" index 52367a4..cf7a1e4 100644 --- "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(1)-\345\217\215\345\260\204.md" +++ "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(1)-\345\217\215\345\260\204.md" @@ -7,7 +7,6 @@ **Contents** - [java基础巩固笔记(1)-反射](#java基础巩固笔记1-反射) -- [反射](#反射) - [反射基本使用](#反射基本使用) - [数组的反射](#数组的反射) - [配置文件加载](#配置文件加载) @@ -17,7 +16,6 @@ --- -# 反射 **反射:将类的属性和方法映射成相应的类。** @@ -94,10 +92,10 @@ hashcode与内存泄露问题 参考java api: >* hashcode一旦生成,不要变 ->* 对象equals方法返回true,则hascode要一致 ->* 反之,equals方法返回false,hascode不一定互异 +>* 对象equals方法返回true,则hashcode要一致 +>* 反之,equals方法返回false,hashcode不一定互异 -如果参与hascode计算的成员变量中途发生变化,则后面remove时失败,造成内存泄露 +如果参与hashcode计算的成员变量中途发生变化,则后面remove时失败,造成内存泄露 ---- @@ -134,7 +132,7 @@ hashcode与内存泄露问题 --- -## 内省(Instropector) & JavaBean +## 内省(Introspector) & JavaBean JavaBean读取属性x的值的流程:变大写、补前缀、获取方法。 ``` diff --git "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(2)-\346\263\233\345\236\213.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(2)-\346\263\233\345\236\213.md" index 59aa512..4397bdc 100644 --- "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(2)-\346\263\233\345\236\213.md" +++ "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(2)-\346\263\233\345\236\213.md" @@ -7,7 +7,6 @@ **Contents** - [java基础巩固笔记(2)-泛型](#java基础巩固笔记2-泛型) -- [泛型](#泛型) - [术语](#术语) - ["?"通配符](#通配符) - [通配符的扩展](#通配符的扩展) @@ -25,8 +24,8 @@ 本文对泛型的基本知识进行较为全面的总结,并附上简短的代码实例,加深记忆。 -# 泛型 -将集合中的元素限定为一个特定的类型。 + +泛型:将集合中的元素限定为一个特定的类型。 ## 术语 @@ -178,7 +177,7 @@ Error:(17, 29) java: 不兼容的类型: 推断类型不符合上限 ``` 但是有一点没搞清楚,我在IDEA里面单步调试,发现结果如下图: -![泛型调试截图-1](http://7xph6d.com1.z0.glb.clouddn.com/javaSE_%E6%B3%9B%E5%9E%8B%E8%B0%83%E8%AF%95%E6%88%AA%E5%9B%BE-1.png) +![泛型调试截图-1](/blogs/img/javaSE_%E6%B3%9B%E5%9E%8B%E8%B0%83%E8%AF%95%E6%88%AA%E5%9B%BE-1.png) 不知道b为什么是Double类型的(但直接`Double b`接收返回值会编译报错)。不知道跟IDE有没有关系,是不是IDE在debug时会显示这个对象最精确的类型? diff --git "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(3)-\347\261\273\345\212\240\350\275\275\345\231\250.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(3)-\347\261\273\345\212\240\350\275\275\345\231\250.md" index 1d244b6..e66d0ee 100644 --- "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(3)-\347\261\273\345\212\240\350\275\275\345\231\250.md" +++ "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(3)-\347\261\273\345\212\240\350\275\275\345\231\250.md" @@ -7,7 +7,6 @@ **Contents** - [java基础巩固笔记(3)-类加载器](#java基础巩固笔记3-类加载器) -- [类加载器](#类加载器) - [默认类加载器](#默认类加载器) - [类加载器的委托机制](#类加载器的委托机制) - [自定义类加载器的编写原理](#自定义类加载器的编写原理) @@ -17,19 +16,16 @@ --- -# 类加载器 java类加载器就是在运行时在JVM中动态地加载所需的类,java类加载器基于三个机制:委托,可见,单一。 -把classpath下的那些.class文件加载进内存,处理后成为字节码,这些工作是类加载器做的。 +把 classpath 下的那些 `.class` 文件加载进内存,处理后形成可以被虚拟机直接使用的 Java 类型,这些工作是类加载器做的。 - **委托机制**指的是将加载类的请求传递给父加载器,如果父加载器找不到或者不能加载这个类,那么再加载他。 - **可见性机制**指的是父加载器加载的类都能被子加载器看见,但是子加载器加载的类父加载器是看不见的。 - **单一性机制**指的是一个类只能被同一种加载器加载一次。 - - ## 默认类加载器 系统默认三个类加载器: @@ -66,14 +62,14 @@ Exception in thread "main" java.lang.NullPointerException ## 类加载器的委托机制 类加载器的树状图 -![类加载器](http://7xph6d.com1.z0.glb.clouddn.com/javaSE_%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8%E7%BB%93%E6%9E%84%E5%9B%BE.png) +![类加载器](/blogs/img/javaSE_%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8%E7%BB%93%E6%9E%84%E5%9B%BE.png) 一般加载类的顺序: - 首先当前线程的类加载器去加载线程中的第一个类 - 如果类A应用了类B,java虚拟机将使用加载类A的类加载器来加载类B -- 还可以直接调用ClassLoader.loadClass()方法来制定某个类加载器去加载某个类 +- 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类 ------------------- diff --git "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\344\273\243\347\220\206.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\344\273\243\347\220\206.md" index e22fc0a..706c592 100644 --- "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\344\273\243\347\220\206.md" +++ "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\344\273\243\347\220\206.md" @@ -26,7 +26,7 @@ - 静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译,也就是说在程序运行前代理类的.class文件就已经存在。 - 动态代理:在程序运行时运用反射机制动态创建生成。 -![代理架构图](http://7xph6d.com1.z0.glb.clouddn.com/javaSE_%E4%BB%A3%E7%90%86%E6%9E%B6%E6%9E%84%E5%9B%BE.png) +![代理架构图](/blogs/img/javaSE_%E4%BB%A3%E7%90%86%E6%9E%B6%E6%9E%84%E5%9B%BE.png) *紫色箭头代表类的继承关系,红色连线表示调用关系* @@ -62,7 +62,7 @@ public class ProxyTest { System.out.println(clazzProxy1); printConstructors(clazzProxy1); printMethods(clazzProxy1); - + } /** @@ -239,14 +239,14 @@ com.sun.proxy.$Proxy0 ### 动态代理的工作原理 -代理类创建时需要传入一个InvocationHandler对象,client调用代理类,代理类的相应方法调用InvocationHandler的的invoke方法,InvocationHandler的的invoke方法(可在其中加入日志记录、时间统计等附加功能)再找目标类的相应方法。 +代理类创建时需要传入一个InvocationHandler对象,client调用代理类,代理类的相应方法调用InvocationHandler的的invoke方法,InvocationHandler的invoke方法(可在其中加入日志记录、时间统计等附加功能)再找目标类的相应方法。 -![动态代理的工作原理图](http://7xph6d.com1.z0.glb.clouddn.com/javaSE_%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%9B%BE.jpg) +![动态代理的工作原理图](/blogs/img/javaSE_%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%9B%BE.jpg) ### 面向切面编程 -把切面的代码以**对象**的形式传递给InvocationHandler的的invoke方法,invoke方法中执行该对象的方法就执行了切面的代码。 - +把切面的代码以**对象**的形式传递给InvocationHandler的invoke方法,invoke方法中执行该对象的方法就执行了切面的代码。 + 所以需要传递两个参数: 1.目标(Object target) diff --git "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(6)-\346\263\250\350\247\243.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(6)-\346\263\250\350\247\243.md" index f7fd489..0d070dd 100644 --- "a/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(6)-\346\263\250\350\247\243.md" +++ "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(6)-\346\263\250\350\247\243.md" @@ -67,7 +67,7 @@ Class C{ ``` RetentionPolicy.SOURCE 注解将被编译器丢弃 RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃 -RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。 +RetentionPolicy.RUNTIME VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息。 ``` - `@Target` diff --git "a/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(1)-Tomcat.md" "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(1)-Tomcat.md" index cf97372..68ab208 100644 --- "a/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(1)-Tomcat.md" +++ "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(1)-Tomcat.md" @@ -91,7 +91,7 @@ mail---------------------------Web应用所在目录 ## Tomcat体系结构 -![Tomcat体系结构](http://7xph6d.com1.z0.glb.clouddn.com/javaweb_tomcat%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84.png) +![Tomcat体系结构](/blogs/img/javaweb_tomcat%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84.png) diff --git "a/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(2)-http\345\205\245\351\227\250.md" "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(2)-http\345\205\245\351\227\250.md" index 86cce6a..64562c8 100644 --- "a/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(2)-http\345\205\245\351\227\250.md" +++ "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(2)-http\345\205\245\351\227\250.md" @@ -48,7 +48,7 @@ ### 响应状态行 -![HTTP响应状态码简表](http://7xph6d.com1.z0.glb.clouddn.com/javaweb_HttpResponseStatus.png) +![HTTP响应状态码简表](/blogs/img/javaweb_HttpResponseStatus.png) 详情可参考 diff --git "a/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(3)-Servlet.md" "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(3)-Servlet.md" index 06c051f..e43df2f 100644 --- "a/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(3)-Servlet.md" +++ "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(3)-Servlet.md" @@ -69,7 +69,7 @@ public class FirstServlet extends GenericServlet{ 时序图 -![servlet的调用过程和生命周期](http://7xph6d.com1.z0.glb.clouddn.com/javaweb_servlet-lifecycle.png) +![servlet的调用过程和生命周期](/blogs/img/javaweb_servlet-lifecycle.png) ## servlet开发的一些细节 @@ -79,7 +79,7 @@ public class FirstServlet extends GenericServlet{ - **通配符**:``的``可以使用通配符,两种固定格式:`*.扩展名`;以`/`开头,以`/*`结尾 -![javaweb_servlet-url匹配.png](http://7xph6d.com1.z0.glb.clouddn.com/javaweb_servlet-url%E5%8C%B9%E9%85%8D.png) +![javaweb_servlet-url匹配.png](/blogs/img/javaweb_servlet-url%E5%8C%B9%E9%85%8D.png) - **对象**:servlet由servlet引擎调用,不能独立运行。客户端多次请求,服务器只创建一个servlet实例,之后驻留内存中继续服务直至web容器退出才销毁它。 - **请求**:服务器针对客户端的每一次请求都会创建新的`request`和`response`对象(它们的生命周期很短),传给`service`方法。 diff --git a/java-base/pom.xml b/java-base/pom.xml index d8bb048..c6536e9 100644 --- a/java-base/pom.xml +++ b/java-base/pom.xml @@ -11,5 +11,4 @@ java-base - \ No newline at end of file diff --git a/java-base/src/main/java/com/brianway/learning/java/base/Binary.java b/java-base/src/main/java/com/brianway/learning/java/base/Binary.java new file mode 100644 index 0000000..2a8849a --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/Binary.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.base; + +/** + * Created by brian on 16/11/10. + * + * TODO 补码/反码相关知识 + * https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html + * http://weihe6666.iteye.com/blog/1190033 + * + * 在计算机中,负数以原码的补码形式表达。 + */ +public class Binary { + public static void main(String[] args) { + int i = 5; + int j = 10; + System.out.println(i + ~j); + + int[] arr = new int[] {3, -2}; + for (int a : arr) { + //原数 + System.out.println("a:" + a + " 二进制:" + Integer.toBinaryString(a)); + // 按位取反 + System.out.println("~a:" + ~a + " 二进制:" + Integer.toBinaryString(~a)); + // 相反数 + System.out.println("-a:" + -a + " 二进制:" + Integer.toBinaryString(-a)); + + System.out.println(-a == ~a + 1); + System.out.println(~a == -a - 1); + } + + } +} diff --git a/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java b/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java index 8983d1e..4ccca61 100644 --- a/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java +++ b/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java @@ -4,14 +4,19 @@ * Created by Brian on 2016/4/14. */ public class FatherClass { + protected static int count = 10; private String name; - public FatherClass(){ + static { + System.out.println("父类的静态属性count初始化:" + count); + } + + public FatherClass() { System.out.println("执行了父类的无参构造方法"); } public FatherClass(String name) { this.name = name; - System.out.println("执行了父类的构造方法FatherClass(String name)"); + System.out.println("执行了父类的构造方法FatherClass(String name) " + name); } } diff --git a/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java b/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java index e923ec9..6ea4cb4 100644 --- a/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java +++ b/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java @@ -2,16 +2,22 @@ /** * Created by Brian on 2016/4/14. - */ - -/** + * * 构造方法调用问题 * 子类构造方法会首先默认调用父类的无参构造方法,无论是否显式写了super(); */ -public class SonClass extends FatherClass{ +public class SonClass extends FatherClass { + + private static int countSon; + + static { + System.out.println("子类可以访问父类的静态属性count " + count); + System.out.println("子类的静态属性countSon初始化:" + countSon); + } + public SonClass(String name) { //super(name); - System.out.println("执行了子类的构造方法SonClass(String name)"); + System.out.println("执行了子类的构造方法SonClass(String name) " + name); } public SonClass() { @@ -26,8 +32,11 @@ public static void main(String[] args) { } /* +父类的静态属性count初始化:10 +子类可以访问父类的静态属性count 10 +子类的静态属性countSon初始化:0 执行了父类的无参构造方法 -执行了子类的构造方法SonClass(String name) +执行了子类的构造方法SonClass(String name) aaa 执行了父类的无参构造方法 执行了子类的无参构造方法 */ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/Boxing.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java similarity index 57% rename from java-base/src/main/java/com/brianway/learning/java/base/Boxing.java rename to java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java index 8ec2160..8ac8da7 100644 --- a/java-base/src/main/java/com/brianway/learning/java/base/Boxing.java +++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java @@ -1,13 +1,11 @@ -package com.brianway.learning.java.base; +package com.brianway.learning.java.base.datatype; /** * Created by Brian on 2016/4/14. - */ - -/** - * TODO - * 待理解。 - * 应该是考装箱和拆箱 + * + * TODO 有些细节待理解 + * + * 主要是考装箱和拆箱 */ public class Boxing { public static void main(String[] args) { @@ -24,16 +22,19 @@ public static void main(String[] args) { System.out.println(c.equals(a + b)); System.out.println(g == (a + b)); System.out.println(g.equals(a + b)); + System.out.println(new Integer(2) == new Integer(2)); } } /* -输出: -true -false -true +输出: 原因: +true 自动装箱,缓存 +false 自动装箱,未缓存 true +true 调用 equals(),比较的是值,而不是对象地址 true false +false 比较的是对象地址 + */ \ No newline at end of file diff --git a/java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java new file mode 100644 index 0000000..45326c8 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/IntegerChanger.java @@ -0,0 +1,44 @@ +package com.brianway.learning.java.base.datatype; + +import java.lang.reflect.Field; + +/** + * Created by brian on 16/11/1. + * + * 涉及到的知识点: + * 1.java 的参数传递都是值传递 + * 2.Integer的内部实现(value,缓存,等等) + * 3.反射操作(可访问性) + * 4.自动装箱和拆箱 + * + * 参考博客 http://www.voidcn.com/blog/zgwangbo/article/p-6101689.html + */ +public class IntegerChanger { + + public static void main(String[] args) { + Integer a = 1, b = 2; + System.out.println("before swap a = " + a + ", b = " + b); + swap(a, b); + System.out.println("after swap a = " + a + ", b = " + b); + + Integer c = 1; + System.out.println("(警告:Integer缓存被改了,代码里:Integer c = 1;) 实际c=" + c); + } + + public static void swap(Integer i1, Integer i2) { + try { + Field f = Integer.class.getDeclaredField("value"); + f.setAccessible(true); + + int tmp = i1; + f.setInt(i1, i2); + f.setInt(i2, tmp); + + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + + } +} \ No newline at end of file diff --git a/java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java new file mode 100644 index 0000000..6cd718b --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/NumberEquation.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.base.datatype; + +/** + * Created by brian on 16/11/10. + * + * 包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱; + * 包装类的equals()方法不处理数据转型. + */ +public class NumberEquation { + public static void main(String[] args) { + Integer i = 42; + Long l = 42l; + Double d = 42.0; + + System.out.println(i.equals(d)); // false + System.out.println(d.equals(l)); // false + System.out.println(i.equals(l)); // false + System.out.println(l.equals(42L)); // true + } +} + +// (i == l),(i == d),(l == d)会出现编译错误 \ No newline at end of file diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java new file mode 100755 index 0000000..9045c41 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/ArrayMaker.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.base.generics; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * 对于泛型中创建数组,使用Array.newInstance()是推荐的方式 + */ +public class ArrayMaker { + private Class kind; + + public ArrayMaker(Class kind) { + this.kind = kind; + } + + @SuppressWarnings("unchecked") + T[] create(int size) { + return (T[]) Array.newInstance(kind, size); + } + + public static void main(String[] args) { + ArrayMaker stringMaker = + new ArrayMaker(String.class); + String[] stringArray = stringMaker.create(9); + System.out.println(Arrays.toString(stringArray)); + } +} +/* Output: +[null, null, null, null, null, null, null, null, null] +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java new file mode 100755 index 0000000..7e37d06 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/BasicBounds.java @@ -0,0 +1,118 @@ +package com.brianway.learning.java.base.generics; + +public class BasicBounds { + public static void main(String[] args) { + Solid solid = + new Solid(new Bounded()); + solid.color(); + solid.getY(); + solid.weight(); + } +} + +interface HasColor { + java.awt.Color getColor(); +} + +class Colored { + T item; + + Colored(T item) { + this.item = item; + } + + T getItem() { + return item; + } + + // The bound allows you to call a method: + java.awt.Color color() { + return item.getColor(); + } +} + +class Dimension { + public int x, y, z; +} + +// This won't work -- class must be first, then interfaces: +// class ColoredDimension { + +// Multiple bounds: +class ColoredDimension { + T item; + + ColoredDimension(T item) { + this.item = item; + } + + T getItem() { + return item; + } + + java.awt.Color color() { + return item.getColor(); + } + + int getX() { + return item.x; + } + + int getY() { + return item.y; + } + + int getZ() { + return item.z; + } +} + +interface Weight { + int weight(); +} + +// As with inheritance, you can have only one +// concrete class but multiple interfaces: +class Solid { + T item; + + Solid(T item) { + this.item = item; + } + + T getItem() { + return item; + } + + java.awt.Color color() { + return item.getColor(); + } + + int getX() { + return item.x; + } + + int getY() { + return item.y; + } + + int getZ() { + return item.z; + } + + int weight() { + return item.weight(); + } +} + +class Bounded + extends Dimension implements HasColor, Weight { + public java.awt.Color getColor() { + return null; + } + + public int weight() { + return 0; + } +} +///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java new file mode 100755 index 0000000..4af0aaa --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/ClassTypeCapture.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.base.generics; + +import java.util.HashMap; +import java.util.Map; + +/** + * 擦除的补偿 + * 显式传递类型的 Class 对象 + */ +public class ClassTypeCapture { + //类型标签 + Class kind; + + Map> types = new HashMap<>(); + + public ClassTypeCapture(Class kind) { + this.kind = kind; + } + + public boolean f(Object arg) { + return kind.isInstance(arg); + } + + public static void main(String[] args) { + ClassTypeCapture ctt1 = + new ClassTypeCapture(Building.class); + System.out.println(ctt1.f(new Building())); + System.out.println(ctt1.f(new House())); + ClassTypeCapture ctt2 = + new ClassTypeCapture(House.class); + System.out.println(ctt2.f(new Building())); + System.out.println(ctt2.f(new House())); + } +} + +class Building { +} + +class House extends Building { +} + +/* Output: +true +true +false +true +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java new file mode 100755 index 0000000..ce639a2 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/CovariantArrays.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.base.generics; + +/** + * 通配符相关类的基础类 + */ +public class CovariantArrays { + public static void main(String[] args) { + Fruit[] fruit = new Apple[10]; + fruit[0] = new Apple(); // OK + fruit[1] = new Jonathan(); // OK + // Runtime type is Apple[], not Fruit[] or Orange[]: + try { + // Compiler allows you to add Fruit: + fruit[0] = new Fruit(); // ArrayStoreException + } catch (Exception e) { + System.out.println(e); + } + try { + // Compiler allows you to add Oranges: + fruit[0] = new Orange(); // ArrayStoreException + } catch (Exception e) { + System.out.println(e); + } + } +} + +class Fruit { +} + +class Apple extends Fruit { +} + +class Jonathan extends Apple { +} + +class Orange extends Fruit { +} + +/* Output: +java.lang.ArrayStoreException: Fruit +java.lang.ArrayStoreException: Orange +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java new file mode 100755 index 0000000..8ccbcf1 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/CreatorGeneric.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.base.generics; + +/** + * 末班方法设计模式 + */ +public class CreatorGeneric { + public static void main(String[] args) { + Creator c = new Creator(); + c.f(); + } +} + +abstract class GenericWithCreate { + final T element; + + GenericWithCreate() { + element = create(); + } + + abstract T create(); +} + +class X { +} + +class Creator extends GenericWithCreate { + X create() { + return new X(); + } + + void f() { + System.out.println(element.getClass().getSimpleName()); + } +} + +/* Output: +X +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java new file mode 100755 index 0000000..0050950 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/ErasedTypeEquivalence.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.base.generics; + +import java.util.ArrayList; + +public class ErasedTypeEquivalence { + public static void main(String[] args) { + Class c1 = new ArrayList().getClass(); + Class c2 = new ArrayList().getClass(); + Class c3 = ArrayList.class; + System.out.println(c1 == c2); + System.out.println(c1 == c3); + } +} +/* Output: +true +true +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java new file mode 100755 index 0000000..a53f978 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/FactoryConstraint.java @@ -0,0 +1,39 @@ +package com.brianway.learning.java.base.generics;//: generics/FactoryConstraint.java + +/** + * 显式工厂 + */ +public class FactoryConstraint { + public static void main(String[] args) { + new Foo2(new IntegerFactory()); + new Foo2(new Widget.Factory()); + } +} + +interface FactoryI { + T create(); +} + +class Foo2 { + private T x; + + public > Foo2(F factory) { + x = factory.create(); + } + +} + +class IntegerFactory implements FactoryI { + public Integer create() { + return 0; + } +} + +class Widget { + public static class Factory implements FactoryI { + public Widget create() { + return new Widget(); + } + } +} +///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java new file mode 100755 index 0000000..b9273fc --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.base.generics;//: generics/GenericArray.java + +/** + * 泛型数组 + */ +public class GenericArray { + private T[] array; + + @SuppressWarnings("unchecked") + public GenericArray(int sz) { + array = (T[]) new Object[sz]; + } + + public void put(int index, T item) { + array[index] = item; + } + + public T get(int index) { + return array[index]; + } + + // Method that exposes the underlying representation: + public T[] rep() { + return array; + } + + public static void main(String[] args) { + GenericArray gai = + new GenericArray(10); + // This causes a ClassCastException: + //! Integer[] ia = gai.rep(); + // This is OK: + Object[] oa = gai.rep(); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java new file mode 100755 index 0000000..21ea014 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArray2.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.base.generics; + +public class GenericArray2 { + private Object[] array; + + public GenericArray2(int sz) { + array = new Object[sz]; + } + + public void put(int index, T item) { + array[index] = item; + } + + @SuppressWarnings("unchecked") + public T get(int index) { + return (T) array[index]; + } + + @SuppressWarnings("unchecked") + public T[] rep() { + return (T[]) array; // Warning: unchecked cast + } + + public static void main(String[] args) { + GenericArray2 gai = + new GenericArray2(10); + for (int i = 0; i < 10; i++) + gai.put(i, i); + for (int i = 0; i < 10; i++) + System.out.print(gai.get(i) + " "); + System.out.println(); + try { + Integer[] ia = gai.rep(); + } catch (Exception e) { + System.out.println(e); + } + } +} /* Output: (Sample) +0 1 2 3 4 5 6 7 8 9 +java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer; +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java new file mode 100755 index 0000000..cafbe61 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericArrayWithTypeToken.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.base.generics; + +import java.lang.reflect.Array; + +public class GenericArrayWithTypeToken { + private T[] array; + + @SuppressWarnings("unchecked") + public GenericArrayWithTypeToken(Class type, int sz) { + array = (T[]) Array.newInstance(type, sz); + } + + public void put(int index, T item) { + array[index] = item; + } + + public T get(int index) { + return array[index]; + } + + // Expose the underlying representation: + public T[] rep() { + return array; + } + + public static void main(String[] args) { + GenericArrayWithTypeToken gai = + new GenericArrayWithTypeToken( + Integer.class, 10); + // This now works: + Integer[] ia = gai.rep(); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java new file mode 100755 index 0000000..715c204 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericMethods.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.base.generics; + +/** + * 泛型方法 + */ +public class GenericMethods { + public void f(T x) { + System.out.println(x.getClass().getName()); + } + + public static void main(String[] args) { + GenericMethods gm = new GenericMethods(); + gm.f(""); + gm.f(1); + gm.f(1.0); + gm.f(1.0F); + gm.f('c'); + gm.f(gm); + } +} +/* Output: +java.lang.String +java.lang.Integer +java.lang.Double +java.lang.Float +java.lang.Character +GenericMethods +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java new file mode 100755 index 0000000..dafc7c0 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericReading.java @@ -0,0 +1,53 @@ +package com.brianway.learning.java.base.generics;//: generics/GenericReading.java + +import java.util.Arrays; +import java.util.List; + +public class GenericReading { + static T readExact(List list) { + return list.get(0); + } + + static List apples = Arrays.asList(new Apple()); + static List fruit = Arrays.asList(new Fruit()); + + // A static method adapts to each call: + static void f1() { + Apple a = readExact(apples); + Fruit f = readExact(fruit); + f = readExact(apples); + } + + // If, however, you have a class, then its type is + // established when the class is instantiated: + static class Reader { + T readExact(List list) { + return list.get(0); + } + } + + static void f2() { + Reader fruitReader = new Reader(); + Fruit f = fruitReader.readExact(fruit); + // Fruit a = fruitReader.readExact(apples); // Error: + // readExact(List) cannot be + // applied to (List). + } + + static class CovariantReader { + T readCovariant(List list) { + return list.get(0); + } + } + + static void f3() { + CovariantReader fruitReader = + new CovariantReader(); + Fruit f = fruitReader.readCovariant(fruit); + Fruit a = fruitReader.readCovariant(apples); + } + + public static void main(String[] args) { + f1(); f2(); f3(); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java new file mode 100755 index 0000000..1a64c5b --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericVarargs.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.base.generics; + +import java.util.ArrayList; +import java.util.List; + +/** + * 可变参数与泛型方法 + */ +public class GenericVarargs { + public static List makeList(T... args) { + List result = new ArrayList(); + for (T item : args) + result.add(item); + return result; + } + + public static void main(String[] args) { + List ls = makeList("A"); + System.out.println(ls); + ls = makeList("A", "B", "C"); + System.out.println(ls); + ls = makeList("ABCDEFFHIJKLMNOPQRSTUVWXYZ".split("")); + System.out.println(ls); + } +} +/* Output: +[A] +[A, B, C] +[, A, B, C, D, E, F, F, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z] +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java new file mode 100755 index 0000000..ac9e9d6 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericWriting.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.base.generics; + +import java.util.ArrayList; +import java.util.List; + +public class GenericWriting { + // 使用确切参数类型 + static void writeExact(List list, T item) { + list.add(item); + } + + static List apples = new ArrayList(); + static List fruit = new ArrayList(); + + static void f1() { + writeExact(apples, new Apple()); + // writeExact(fruit, new Apple()); // Error: + // Incompatible types: found Fruit, required Apple + } + + // + static void + writeWithWildcard(List list, T item) { + list.add(item); + } + + static void f2() { + writeWithWildcard(apples, new Apple()); + writeWithWildcard(fruit, new Apple()); + } + + public static void main(String[] args) { + f1(); + f2(); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java new file mode 100755 index 0000000..5c9722d --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/GenericsAndCovariance.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.base.generics; + +import java.util.ArrayList; +import java.util.List; + +/** + * + */ +public class GenericsAndCovariance { + public static void main(String[] args) { + // Wildcards allow covariance: + List flist = new ArrayList(); + // Compile Error: can't add any type of object: + // flist.add(new Apple()); + // flist.add(new Fruit()); + // flist.add(new Object()); + flist.add(null); // Legal but uninteresting + // We know that it returns at least Fruit: + Fruit f = flist.get(0); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java new file mode 100755 index 0000000..70c2387 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/Holder.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.base.generics; + + +public class Holder { + private T value; + + public Holder() { + } + + public Holder(T val) { + value = val; + } + + public void set(T val) { + value = val; + } + + public T get() { + return value; + } + + public boolean equals(Object obj) { + return value.equals(obj); + } + + public static void main(String[] args) { + Holder Apple = new Holder(new Apple()); + Apple d = Apple.get(); + Apple.set(d); + // Holder Fruit = Apple; // Cannot upcast + Holder fruit = Apple; // OK + Fruit p = fruit.get(); + d = (Apple) fruit.get(); // Returns 'Object' + try { + Orange c = (Orange) fruit.get(); // No warning + } catch (Exception e) { + System.out.println(e); + } + // fruit.set(new Apple()); // Cannot call set() + // fruit.set(new Fruit()); // Cannot call set() + System.out.println(fruit.equals(d)); // OK + } +} +/* Output: (Sample) +java.lang.ClassCastException: com.brianway.learning.java.base.generics.Apple cannot be cast to com.brianway.learning.java.base.generics.Orange +true +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java new file mode 100755 index 0000000..4995479 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/InheritBounds.java @@ -0,0 +1,65 @@ +package com.brianway.learning.java.base.generics; + +public class InheritBounds { + public static void main(String[] args) { + Solid2 solid2 = + new Solid2(new Bounded()); + solid2.color(); + solid2.getY(); + solid2.weight(); + } +} + +class HoldItem { + T item; + + HoldItem(T item) { + this.item = item; + } + + T getItem() { + return item; + } +} + +class Colored2 extends HoldItem { + Colored2(T item) { + super(item); + } + + java.awt.Color color() { + return item.getColor(); + } +} + +class ColoredDimension2 + extends Colored2 { + ColoredDimension2(T item) { + super(item); + } + + int getX() { + return item.x; + } + + int getY() { + return item.y; + } + + int getZ() { + return item.z; + } +} + +class Solid2 + extends ColoredDimension2 { + Solid2(T item) { + super(item); + } + + int weight() { + return item.weight(); + } +} + +///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java new file mode 100755 index 0000000..c7bd90f --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/InstantiateGenericType.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.base.generics; + +public class InstantiateGenericType { + public static void main(String[] args) { + ClassAsFactory fe = + new ClassAsFactory(Employee.class); + System.out.println("ClassAsFactory succeeded"); + try { + ClassAsFactory fi = + new ClassAsFactory(Integer.class); + } catch (Exception e) { + System.out.println("ClassAsFactory failed"); + } + } +} + +class ClassAsFactory { + T x; + + public ClassAsFactory(Class kind) { + try { + x = kind.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} + +class Employee { +} + +/* Output: +ClassAsFactory succeeded +ClassAsFactory failed +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java new file mode 100755 index 0000000..c58ea6c --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/LinkedStack.java @@ -0,0 +1,52 @@ +package com.brianway.learning.java.base.generics; + +/** + * A stack implemented with an internal linked structure. + */ +public class LinkedStack { + private static class Node { + U item; + Node next; + + Node() { + item = null; next = null; + } + + Node(U item, Node next) { + this.item = item; + this.next = next; + } + + boolean end() { + return item == null && next == null; + } + } + + private Node top = new Node(); // End sentinel + + public void push(T item) { + top = new Node(item, top); + } + + public T pop() { + T result = top.item; + if (!top.end()) { + top = top.next; + } + return result; + } + + public static void main(String[] args) { + LinkedStack lss = new LinkedStack(); + for (String s : "Phasers on stun!".split(" ")) + lss.push(s); + String s; + while ((s = lss.pop()) != null) + System.out.println(s); + } +} +/* Output: +stun! +on +Phasers +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java new file mode 100755 index 0000000..617a224 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/LostInformation.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.base.generics;//: generics/LostInformation.java + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LostInformation { + public static void main(String[] args) { + List list = new ArrayList(); + Map map = new HashMap(); + Quark quark = new Quark(); + Particle p = new Particle(); + System.out.println(Arrays.toString( + list.getClass().getTypeParameters())); + System.out.println(Arrays.toString( + map.getClass().getTypeParameters())); + System.out.println(Arrays.toString( + quark.getClass().getTypeParameters())); + System.out.println(Arrays.toString( + p.getClass().getTypeParameters())); + } +} + +class Frob { +} + +class Fnorkle { +} + +class Quark { +} + +class Particle { +} + +/* Output: +[E] +[K, V] +[Q] +[POSITION, MOMENTUM] +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java new file mode 100755 index 0000000..fc4f031 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/SuperTypeWildcards.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.base.generics; + +import java.util.ArrayList; +import java.util.List; + +/** + * 逆变 + * 超类型通配符 + */ +public class SuperTypeWildcards { + static void writeTo(List apples) { + apples.add(new Apple()); + apples.add(new Jonathan()); + // apples.add(new Fruit()); // Error + } + + public static void main(String[] args) { + SuperTypeWildcards.writeTo(new ArrayList()); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java b/java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java new file mode 100755 index 0000000..6618fdb --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/generics/Wildcards.java @@ -0,0 +1,130 @@ +package com.brianway.learning.java.base.generics; + +/** + * Exploring the meaning of wildcards. + */ +public class Wildcards { + // Raw argument: + static void rawArgs(Holder holder, Object arg) { + // holder.set(arg); // Warning: + // Unchecked call to set(T) as a + // member of the raw type Holder + // holder.set(new Wildcards()); // Same warning + + // Can't do this; don't have any 'T': + // T t = holder.get(); + + // OK, but type information has been lost: + Object obj = holder.get(); + } + + // Similar to rawArgs(), but errors instead of warnings: + static void unboundedArg(Holder holder, Object arg) { + // holder.set(arg); // Error: + // set(capture of ?) in Holder + // cannot be applied to (Object) + // holder.set(new Wildcards()); // Same error + + // Can't do this; don't have any 'T': + // T t = holder.get(); + + // OK, but type information has been lost: + Object obj = holder.get(); + } + + static T exact1(Holder holder) { + T t = holder.get(); + return t; + } + + static T exact2(Holder holder, T arg) { + holder.set(arg); + T t = holder.get(); + return t; + } + + static + T wildSubtype(Holder holder, T arg) { + // holder.set(arg); // Error: + // set(capture of ? extends T) in + // Holder + // cannot be applied to (T) + T t = holder.get(); + return t; + } + + static + void wildSupertype(Holder holder, T arg) { + holder.set(arg); + // T t = holder.get(); // Error: + // Incompatible types: found Object, required T + + // OK, but type information has been lost: + Object obj = holder.get(); + } + + public static void main(String[] args) { + Holder raw = new Holder(); + // Or: + raw = new Holder(); + Holder qualified = new Holder(); + Holder unbounded = new Holder(); + Holder bounded = new Holder(); + Long lng = 1L; + + rawArgs(raw, lng); + rawArgs(qualified, lng); + rawArgs(unbounded, lng); + rawArgs(bounded, lng); + + unboundedArg(raw, lng); + unboundedArg(qualified, lng); + unboundedArg(unbounded, lng); + unboundedArg(bounded, lng); + + // Object r1 = exact1(raw); // Warnings: + // Unchecked conversion from Holder to Holder + // Unchecked method invocation: exact1(Holder) + // is applied to (Holder) + Long r2 = exact1(qualified); + Object r3 = exact1(unbounded); // Must return Object + Long r4 = exact1(bounded); + + // Long r5 = exact2(raw, lng); // Warnings: + // Unchecked conversion from Holder to Holder + // Unchecked method invocation: exact2(Holder,T) + // is applied to (Holder,Long) + Long r6 = exact2(qualified, lng); + // Long r7 = exact2(unbounded, lng); // Error: + // exact2(Holder,T) cannot be applied to + // (Holder,Long) + // Long r8 = exact2(bounded, lng); // Error: + // exact2(Holder,T) cannot be applied + // to (Holder,Long) + + // Long r9 = wildSubtype(raw, lng); // Warnings: + // Unchecked conversion from Holder + // to Holder + // Unchecked method invocation: + // wildSubtype(Holder,T) is + // applied to (Holder,Long) + Long r10 = wildSubtype(qualified, lng); + // OK, but can only return Object: + Object r11 = wildSubtype(unbounded, lng); + Long r12 = wildSubtype(bounded, lng); + + // wildSupertype(raw, lng); // Warnings: + // Unchecked conversion from Holder + // to Holder + // Unchecked method invocation: + // wildSupertype(Holder,T) + // is applied to (Holder,Long) + wildSupertype(qualified, lng); + // wildSupertype(unbounded, lng); // Error: + // wildSupertype(Holder,T) cannot be + // applied to (Holder,Long) + // wildSupertype(bounded, lng); // Error: + // wildSupertype(Holder,T) cannot be + // applied to (Holder,Long) + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java new file mode 100644 index 0000000..09de444 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/ClassCreator.java @@ -0,0 +1,16 @@ +package com.brianway.learning.java.base.innerclass; + +/** + * Created by brian on 16/11/10. + * + * 创建内部类的测试类 + */ +public class ClassCreator { + public static void main(String[] args) { + //在其他类里创建非静态内部类和静态内部类 + EnclosingOne eo = new EnclosingOne(); + EnclosingOne.InsideOne io = eo.new InsideOne(); + EnclosingOne.InsideTwo it = new EnclosingOne.InsideTwo(); + } + +} diff --git a/java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java new file mode 100644 index 0000000..4718fd4 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/innerclass/EnclosingOne.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.base.innerclass; + +/** + * Created by brian on 16/11/10. + */ +public class EnclosingOne { + + public class InsideOne { + + } + + static public class InsideTwo { + + } + + public static void main(String[] args) { + EnclosingOne eo = new EnclosingOne(); + InsideOne io = eo.new InsideOne(); + InsideTwo it = new InsideTwo(); + } +} diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java new file mode 100755 index 0000000..c5e7d6f --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/BoundedClassReferences.java @@ -0,0 +1,10 @@ +package com.brianway.learning.java.base.typeinfo; + +public class BoundedClassReferences { + public static void main(String[] args) { + Class bounded = int.class; + bounded = double.class; + bounded = Number.class; + // Or anything else derived from Number. + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java new file mode 100755 index 0000000..da64ce4 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassCasts.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.base.typeinfo; + +class Building { +} + +class House extends Building { +} + +public class ClassCasts { + public static void main(String[] args) { + Building b = new House(); + Class houseType = House.class; + House h = houseType.cast(b); + h = (House) b; // ... or just do this. + + try { + Class hClass = House.class; + //Produces exact type + House house = hClass.newInstance(); + Class up = hClass.getSuperclass(); + // won't compile: + //Class up2 = hClass.getSuperclass(); + + //Only produces Object + Object obj = up.newInstance(); + + System.out.println(house); + System.out.println(obj); + } catch (Exception e) { + e.printStackTrace(); + } + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java new file mode 100755 index 0000000..0703121 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/ClassInitialization.java @@ -0,0 +1,64 @@ +package com.brianway.learning.java.base.typeinfo; + +import java.util.Random; + +/** + * 1.仅使用.class语法来获得对类的引用不会引发初始化 + * 2."编译器常量",无需类初始化即可读取 + * 3.static final域不一定是编译器常量,static非final域一定不是 + */ +public class ClassInitialization { + public static Random rand = new Random(47); + + public static void main(String[] args) throws Exception { + Class initable = Initable.class; + System.out.println("After creating Initable ref"); + // Does not trigger initialization: + System.out.println(Initable.staticFinal); + // Does trigger initialization: + System.out.println(Initable.staticFinal2); + // Does trigger initialization: + System.out.println(Initable2.staticNonFinal); + Class initable3 = Class.forName("com.brianway.learning.java.base.typeinfo.Initable3"); + System.out.println("After creating Initable3 ref"); + System.out.println(Initable3.staticNonFinal); + } +} + +class Initable { + static final int staticFinal = 47; + static final int staticFinal2 = + ClassInitialization.rand.nextInt(1000); + + static { + System.out.println("Initializing Initable"); + } +} + +class Initable2 { + static int staticNonFinal = 147; + + static { + System.out.println("Initializing Initable2"); + } +} + +class Initable3 { + static int staticNonFinal = 74; + + static { + System.out.println("Initializing Initable3"); + } +} + +/* Output: +After creating Initable ref +47 +Initializing Initable +258 +Initializing Initable2 +147 +Initializing Initable3 +After creating Initable3 ref +74 +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java new file mode 100755 index 0000000..5547fde --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FamilyVsExactType.java @@ -0,0 +1,54 @@ +package com.brianway.learning.java.base.typeinfo; + +/** + * The difference between instanceof and class. + */ +public class FamilyVsExactType { + static void test(Object x) { + System.out.println("Testing x of type " + x.getClass()); + System.out.println("x instanceof Base " + (x instanceof Base)); + System.out.println("x instanceof Derived " + (x instanceof Derived)); + System.out.println("Base.isInstance(x) " + Base.class.isInstance(x)); + System.out.println("Derived.isInstance(x) " + + Derived.class.isInstance(x)); + System.out.println("x.getClass() == Base.class " + + (x.getClass() == Base.class)); + System.out.println("x.getClass() == Derived.class " + + (x.getClass() == Derived.class)); + System.out.println("x.getClass().equals(Base.class)) " + + (x.getClass().equals(Base.class))); + System.out.println("x.getClass().equals(Derived.class)) " + + (x.getClass().equals(Derived.class))); + } + + public static void main(String[] args) { + test(new Base()); + test(new Derived()); + } +} + +class Base { +} + +class Derived extends Base { +} +/* Output: +Testing x of type class typeinfo.Base +x instanceof Base true +x instanceof Derived false +Base.isInstance(x) true +Derived.isInstance(x) false +x.getClass() == Base.class true +x.getClass() == Derived.class false +x.getClass().equals(Base.class)) true +x.getClass().equals(Derived.class)) false +Testing x of type class typeinfo.Derived +x instanceof Base true +x instanceof Derived true +Base.isInstance(x) true +Derived.isInstance(x) true +x.getClass() == Base.class false +x.getClass() == Derived.class true +x.getClass().equals(Base.class)) false +x.getClass().equals(Derived.class)) true +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java new file mode 100755 index 0000000..437f452 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/FilledList.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.base.typeinfo; + +import java.util.ArrayList; +import java.util.List; + +class CountedInteger { + private static long counter; + private final long id = counter++; + + public String toString() { + return Long.toString(id); + } +} + +public class FilledList { + private Class type; + + public FilledList(Class type) { + this.type = type; + } + + public List create(int nElements) { + List result = new ArrayList(); + try { + for (int i = 0; i < nElements; i++) + result.add(type.newInstance()); + } catch (Exception e) { + throw new RuntimeException(e); + } + return result; + } + + public static void main(String[] args) { + FilledList fl = + new FilledList(CountedInteger.class); + System.out.println(fl.create(15)); + } +} +/* Output: +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java new file mode 100755 index 0000000..23e0718 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/GenericClassReferences.java @@ -0,0 +1,15 @@ +package com.brianway.learning.java.base.typeinfo; + +public class GenericClassReferences { + public static void main(String[] args) { + + Class genericIntClass = int.class; + genericIntClass = Integer.class; // Same thing + + Class intClass = int.class; + intClass = double.class; + // genericIntClass = double.class; // Illegal + + System.out.println(int.class == Integer.class); + } +} ///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java new file mode 100755 index 0000000..7b44a9e --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleDynamicProxy.java @@ -0,0 +1,52 @@ +package com.brianway.learning.java.base.typeinfo;//: typeinfo/SimpleDynamicProxy.java + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +class DynamicProxyHandler implements InvocationHandler { + private Object proxied; + + public DynamicProxyHandler(Object proxied) { + this.proxied = proxied; + } + + public Object + invoke(Object proxy, Method method, Object[] args) + throws Throwable { + System.out.println("**** proxy: " + proxy.getClass().getSimpleName() + + ", method: " + method + ", args: " + args); + if (args != null) { + for (Object arg : args) + System.out.println(" " + arg); + } + return method.invoke(proxied, args); + } +} + +class SimpleDynamicProxy { + public static void consumer(Interface iface) { + iface.doSomething(); + iface.somethingElse("bonobo"); + } + + public static void main(String[] args) { + RealObject real = new RealObject(); + consumer(real); + // Insert a proxy and call again: + Interface proxy = (Interface) Proxy.newProxyInstance( + Interface.class.getClassLoader(), + new Class[] {Interface.class}, + new DynamicProxyHandler(real)); + consumer(proxy); + } +} +/* Output: (95% match) +doSomething +somethingElse bonobo +**** proxy: $Proxy0, method: public abstract void com.brianway.learning.java.base.typeinfo.Interface.doSomething(), args: null +doSomething +**** proxy: $Proxy0, method: public abstract void com.brianway.learning.java.base.typeinfo.Interface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@d716361 + bonobo +somethingElse bonobo +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java new file mode 100755 index 0000000..7047cb0 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/SimpleProxyDemo.java @@ -0,0 +1,56 @@ +package com.brianway.learning.java.base.typeinfo; + +interface Interface { + void doSomething(); + + void somethingElse(String arg); +} + +class RealObject implements Interface { + public void doSomething() { + System.out.println("doSomething"); + } + + public void somethingElse(String arg) { + System.out.println("somethingElse " + arg); + } +} + +class SimpleProxy implements Interface { + private Interface proxied; + + public SimpleProxy(Interface proxied) { + this.proxied = proxied; + } + + public void doSomething() { + System.out.println("SimpleProxy doSomething"); + proxied.doSomething(); + } + + public void somethingElse(String arg) { + System.out.println("SimpleProxy somethingElse " + arg); + proxied.somethingElse(arg); + } +} + +class SimpleProxyDemo { + public static void consumer(Interface iface) { + iface.doSomething(); + iface.somethingElse("bonobo"); + } + + public static void main(String[] args) { + consumer(new RealObject()); + consumer(new SimpleProxy(new RealObject())); + } +} + +/* Output: +doSomething +somethingElse bonobo +SimpleProxy doSomething +doSomething +SimpleProxy somethingElse bonobo +somethingElse bonobo +*///:~ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java new file mode 100755 index 0000000..cca198a --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/typeinfo/WildcardClassReferences.java @@ -0,0 +1,8 @@ +package com.brianway.learning.java.base.typeinfo; + +public class WildcardClassReferences { + public static void main(String[] args) { + Class intClass = int.class; + intClass = double.class; + } +} ///:~ diff --git a/java-container/pom.xml b/java-container/pom.xml new file mode 100644 index 0000000..7f8d9ed --- /dev/null +++ b/java-container/pom.xml @@ -0,0 +1,14 @@ + + + + java-learning + com.brianway.learning.java + 1.0-SNAPSHOT + + 4.0.0 + + java-container + + \ No newline at end of file diff --git a/java-io/pom.xml b/java-io/pom.xml new file mode 100644 index 0000000..048ab63 --- /dev/null +++ b/java-io/pom.xml @@ -0,0 +1,20 @@ + + + + java-learning + com.brianway.learning.java + 1.0-SNAPSHOT + + 4.0.0 + + java-io + + + + junit + junit + + + \ No newline at end of file diff --git a/java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java b/java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java new file mode 100644 index 0000000..213424d --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/BufferedInputFile.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.io; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +/** + * Created by brian on 16/11/28. + */ +public class BufferedInputFile { + public static String read(String filename) throws IOException { + BufferedReader in = new BufferedReader( + new FileReader(filename)); + String s; + StringBuilder sb = new StringBuilder(); + while ((s = in.readLine()) != null) { + sb.append(s).append("\n"); + } + in.close(); + return sb.toString(); + } + + public static void main(String[] args) throws IOException { + String file = BufferedInputFile.class.getResource("/").getPath() + + "/infile.txt"; + System.out.print(read(file)); + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/io/DirList.java b/java-io/src/main/java/com/brianway/learning/java/io/DirList.java new file mode 100644 index 0000000..ca883af --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/DirList.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.io; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.Arrays; +import java.util.regex.Pattern; + +/** + * Created by brian on 16/11/28. + * 列举文件/文件夹 + */ +public class DirList { + public static void main(final String[] args) { + File path = new File("."); + String[] list; + if (args.length == 0) { + list = path.list(); + } else { + list = path.list(new FilenameFilter() { + private Pattern pattern = Pattern.compile(args[0]); // final String[] args + + public boolean accept(File dir, String name) { + return pattern.matcher(name).matches(); + } + }); + } + + if (list == null) return; + Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); + for (String dirItem : list) { + System.out.println(dirItem); + } + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/io/Echo.java b/java-io/src/main/java/com/brianway/learning/java/io/Echo.java new file mode 100644 index 0000000..34ba225 --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/Echo.java @@ -0,0 +1,25 @@ +package com.brianway.learning.java.io; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; + +/** + * Created by brian on 16/11/28. + * + * 从标准输入中读取,并将 System.out 转换成 PrintWriter + */ +public class Echo { + public static void main(String[] args) throws IOException { + BufferedReader stdin = new BufferedReader( + new InputStreamReader(System.in)); + PrintWriter out = new PrintWriter(System.out, true);// 开启自动清空 + + String s; + while ((s = stdin.readLine()) != null && s.length() != 0) { + //System.out.println(s); + out.println(s); + } + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java new file mode 100644 index 0000000..2c4b171 --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/FileOutput.java @@ -0,0 +1,60 @@ +package com.brianway.learning.java.io; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringReader; + +/** + * Created by brian on 16/11/28. + */ +public class FileOutput { + + /** + * 基本的文件输出 + */ + public static void basic(String infile, String outfile) throws IOException { + BufferedReader in = new BufferedReader( + new StringReader( + BufferedInputFile.read(infile))); + PrintWriter out = new PrintWriter( + new BufferedWriter(new FileWriter(outfile))); + int lineCount = 1; + String s; + while ((s = in.readLine()) != null) { + out.println(lineCount++ + ": " + s); + } + out.close(); + System.out.println(BufferedInputFile.read(outfile)); + } + + /** + * 文本文件输出的快捷方式 + */ + public static void shortcut(String infile, String outfile) throws IOException { + BufferedReader in = new BufferedReader( + new StringReader( + BufferedInputFile.read(infile))); + PrintWriter out = new PrintWriter(outfile); + int lineCount = 1; + String s; + while ((s = in.readLine()) != null) { + out.println(lineCount++ + ": " + s); + } + out.close(); + System.out.println(BufferedInputFile.read(outfile)); + } + + public static void main(String[] args) throws IOException { + String parent = FileOutput.class.getResource("/").getPath(); + String infile = parent + "/infile.txt"; + + String outfile = parent + "/BasicOut"; + basic(infile, outfile); + + outfile = parent + "ShortcutOut"; + shortcut(infile, outfile); + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java b/java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java new file mode 100755 index 0000000..d48d7dc --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/MakeDirectories.java @@ -0,0 +1,86 @@ +package com.brianway.learning.java.io; +//: io/MakeDirectories.java +// Demonstrates the use of the File class to +// create directories and manipulate files. +// {Args: MakeDirectoriesTest} + +import java.io.File; + +public class MakeDirectories { + private static void usage() { + System.err.println( + "Usage:MakeDirectories path1 ...\n" + + "Creates each path\n" + + "Usage:MakeDirectories -d path1 ...\n" + + "Deletes each path\n" + + "Usage:MakeDirectories -r path1 path2\n" + + "Renames from path1 to path2"); + System.exit(1); + } + + private static void fileData(File f) { + System.out.println( + "Absolute path: " + f.getAbsolutePath() + + "\n Can read: " + f.canRead() + + "\n Can write: " + f.canWrite() + + "\n getName: " + f.getName() + + "\n getParent: " + f.getParent() + + "\n getPath: " + f.getPath() + + "\n length: " + f.length() + + "\n lastModified: " + f.lastModified()); + if (f.isFile()) { + System.out.println("It's a file"); + } else if (f.isDirectory()) { + System.out.println("It's a directory"); + } + } + + public static void main(String[] args) { + if (args.length < 1) usage(); + if (args[0].equals("-r")) { + if (args.length != 3) usage(); + File + old = new File(args[1]), + rname = new File(args[2]); + old.renameTo(rname); + fileData(old); + fileData(rname); + return; // Exit main + } + int count = 0; + boolean del = false; + if (args[0].equals("-d")) { + count++; + del = true; + } + count--; + while (++count < args.length) { + File f = new File(args[count]); + if (f.exists()) { + System.out.println(f + " exists"); + if (del) { + System.out.println("deleting..." + f); + f.delete(); + } + } else { // Doesn't exist + if (!del) { + f.mkdirs(); + System.out.println("created " + f); + } + } + fileData(f); + } + } +} +/* Output: (80% match) +created MakeDirectoriesTest +Absolute path: d:\aaa-TIJ4\code\io\MakeDirectoriesTest + Can read: true + Can write: true + getName: MakeDirectoriesTest + getParent: null + getPath: MakeDirectoriesTest + length: 0 + lastModified: 1101690308831 +It's a directory +*///:~ diff --git a/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java b/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java new file mode 100755 index 0000000..7b459ed --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/MemoryInput.java @@ -0,0 +1,55 @@ +package com.brianway.learning.java.io; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.StringReader; + +/** + * Created by brian on 16/11/28. + * 内存输入 + */ + +public class MemoryInput { + + /** + * 从内存输入 + */ + public static void useStringReader(String filename) { + try { + StringReader in = new StringReader( + BufferedInputFile.read(filename)); + int c; + while ((c = in.read()) != -1) + System.out.print((char) c); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + /** + * 格式化的内存输入 + */ + public static void readFormattedInput(String filename) { + try { + DataInputStream in = new DataInputStream( + new ByteArrayInputStream( + BufferedInputFile.read(filename) + .getBytes())); + while (in.available() != 0) { + System.out.print((char) in.readByte()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) + throws IOException { + String filename = MemoryInput.class.getResource("/").getPath() + + "/infile.txt"; + useStringReader(filename); + readFormattedInput(filename); + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java b/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java new file mode 100755 index 0000000..cf574ba --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/io/TextFile.java @@ -0,0 +1,104 @@ +package com.brianway.learning.java.io; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.TreeSet; + +/** + * Static functions for reading and writing text files as + * a single string, and treating a file as an ArrayList. + */ +public class TextFile extends ArrayList { + // Read a file as a single string: + public static String read(String fileName) { + StringBuilder sb = new StringBuilder(); + try { + BufferedReader in = new BufferedReader( + new FileReader( + new File(fileName).getAbsoluteFile())); + try { + String s; + while ((s = in.readLine()) != null) { + sb.append(s); + sb.append("\n"); + } + } finally { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return sb.toString(); + } + + // Write a single file in one method call: + public static void write(String fileName, String text) { + try { + PrintWriter out = new PrintWriter( + new File(fileName).getAbsoluteFile()); + try { + out.print(text); + } finally { + out.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // Read a file, split by any regular expression: + public TextFile(String fileName, String splitter) { + super(Arrays.asList(read(fileName).split(splitter))); + // Regular expression split() often leaves an empty + // String at the first position: + if (get(0).equals("")) remove(0); + } + + // Normally read by lines: + public TextFile(String fileName) { + this(fileName, "\n"); + } + + public void write(String fileName) { + try { + PrintWriter out = new PrintWriter( + new File(fileName).getAbsoluteFile()); + try { + for (String item : this) + out.println(item); + } finally { + out.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // Simple test: + public static void main(String[] args) { + String parent = TextFile.class.getResource("/").getPath(); + String inFileName = parent + "/infile.txt"; + + String file = read(inFileName); + write(parent + "/text.txt", file); + TextFile text = new TextFile(parent + "/text.txt"); + text.write(parent + "test2.txt"); + // Break into unique sorted list of words: + TreeSet words = new TreeSet<>( + new TextFile(inFileName, "\\W+")); + // Display the capitalized words: + System.out.println(words.headSet("a")); + + } +} + diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/example/BufferToText.java b/java-io/src/main/java/com/brianway/learning/java/nio/example/BufferToText.java new file mode 100755 index 0000000..718fe64 Binary files /dev/null and b/java-io/src/main/java/com/brianway/learning/java/nio/example/BufferToText.java differ diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/example/ChannelCopy.java b/java-io/src/main/java/com/brianway/learning/java/nio/example/ChannelCopy.java new file mode 100644 index 0000000..f439a48 --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/example/ChannelCopy.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.nio.example; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +/** + * Created by brian on 16/11/29. + */ +public class ChannelCopy { + + private static final int BSIZE = 1024; + + public static void main(String[] args) throws IOException { + String parent = ChannelCopy.class.getResource("/").getPath(); + String infile = parent + "/infile.txt"; + String outCopy = parent + "/outCopy.txt"; + String outTransferTo = parent + "/outTransferTo.txt"; + copy(infile, outCopy); + transferTo(infile, outTransferTo); + } + + private static void copy(String infile, String outfile) throws IOException { + FileChannel + in = new FileInputStream(infile).getChannel(), + out = new FileOutputStream(outfile).getChannel(); + ByteBuffer buffer = ByteBuffer.allocate(BSIZE); + while (in.read(buffer) != -1) { + buffer.flip(); // prepare for writing + out.write(buffer); + buffer.clear(); // prepare for reading + } + } + + private static void transferTo(String infile, String outfile) throws IOException { + FileChannel + in = new FileInputStream(infile).getChannel(), + out = new FileOutputStream(outfile).getChannel(); + in.transferTo(0, in.size(), out); + // Or: + // out.transferFrom(in,0,in.size()); + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/example/Endians.java b/java-io/src/main/java/com/brianway/learning/java/nio/example/Endians.java new file mode 100644 index 0000000..8cd74be --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/example/Endians.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.nio.example; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +/** + * Created by brian on 16/11/29. + * + * "big endian"(高位优先),将最重要的字节放在地址最低的存储器单元; + * "little endian"(低位优先),将最重要的字节放在地址最高的存储器单元; + * + * ByteBuffer 是以高位优先的形式存储数据的。 + */ +public class Endians { + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.wrap(new byte[12]); + bb.asCharBuffer().put("abcdef"); + System.out.println(Arrays.toString(bb.array())); + + bb.rewind(); + bb.order(ByteOrder.BIG_ENDIAN); + bb.asCharBuffer().put("abcdef"); + System.out.println(Arrays.toString(bb.array())); + + bb.rewind(); + bb.order(ByteOrder.LITTLE_ENDIAN); + bb.asCharBuffer().put("abcdef"); + System.out.println(Arrays.toString(bb.array())); + } +} +/* Output: +[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] +[0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102] +[97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0] +*///:~ diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/example/GetChannel.java b/java-io/src/main/java/com/brianway/learning/java/nio/example/GetChannel.java new file mode 100644 index 0000000..4a0f22c --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/example/GetChannel.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.nio.example; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +/** + * Created by brian on 16/11/29. + */ +public class GetChannel { + private static final int BSIZE = 1024; + + public static void main(String[] args) throws IOException { + String parent = GetChannel.class.getResource("/").getPath(); + String filename = parent + "/data.txt"; + write(filename); + addToEnd(filename); + read(filename); + } + + private static void write(String filename) throws IOException { + FileChannel fc = new FileOutputStream(filename).getChannel(); + fc.write(ByteBuffer.wrap("Some text ".getBytes())); + fc.close(); + } + + private static void addToEnd(String filename) throws IOException { + FileChannel fc = new RandomAccessFile(filename, "rw").getChannel(); + fc.position(fc.size()); + fc.write(ByteBuffer.wrap("Some more ".getBytes())); + fc.close(); + } + + private static void read(String filename) throws IOException { + FileChannel fc = new FileInputStream(filename).getChannel(); + ByteBuffer buff = ByteBuffer.allocate(BSIZE); + fc.read(buff); + buff.flip(); + while (buff.hasRemaining()) { + System.out.print((char) buff.get()); + } + fc.close(); + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/example/ViewBuffers.java b/java-io/src/main/java/com/brianway/learning/java/nio/example/ViewBuffers.java new file mode 100755 index 0000000..ba703dd --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/example/ViewBuffers.java @@ -0,0 +1,78 @@ +package com.brianway.learning.java.nio.example;//: io/ViewBuffers.java + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + +/** + * Created by brian on 16/11/29. + * + * 通过在同一个 ByteBuffer 上建立不同的试图缓冲器, + * 将同一字节序列翻译成short,int,float,long,double等类型的数据 + */ + +public class ViewBuffers { + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.wrap( + new byte[] {0, 0, 0, 0, 0, 0, 0, 'a'}); + bb.rewind(); + System.out.print("Byte Buffer "); + while (bb.hasRemaining()) + System.out.print(bb.position() + " -> " + bb.get() + ", "); + System.out.println(); + + CharBuffer cb = + ((ByteBuffer) bb.rewind()).asCharBuffer(); + System.out.println("Char Buffer "); + while (cb.hasRemaining()) + System.out.print(cb.position() + " -> " + cb.get() + ", "); + System.out.println(); + + FloatBuffer fb = + ((ByteBuffer) bb.rewind()).asFloatBuffer(); + System.out.print("Float Buffer "); + while (fb.hasRemaining()) + System.out.print(fb.position() + " -> " + fb.get() + ", "); + System.out.println(); + + IntBuffer ib = + ((ByteBuffer) bb.rewind()).asIntBuffer(); + System.out.print("Int Buffer "); + while (ib.hasRemaining()) + System.out.print(ib.position() + " -> " + ib.get() + ", "); + System.out.println(); + + LongBuffer lb = + ((ByteBuffer) bb.rewind()).asLongBuffer(); + System.out.print("Long Buffer "); + while (lb.hasRemaining()) + System.out.print(lb.position() + " -> " + lb.get() + ", "); + System.out.println(); + + ShortBuffer sb = + ((ByteBuffer) bb.rewind()).asShortBuffer(); + System.out.print("Short Buffer "); + while (sb.hasRemaining()) + System.out.print(sb.position() + " -> " + sb.get() + ", "); + System.out.println(); + + DoubleBuffer db = + ((ByteBuffer) bb.rewind()).asDoubleBuffer(); + System.out.print("Double Buffer "); + while (db.hasRemaining()) + System.out.print(db.position() + " -> " + db.get() + ", "); + } +} +/* Output: +Byte Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0, 5 -> 0, 6 -> 0, 7 -> 97, +Char Buffer 0 -> , 1 -> , 2 -> , 3 -> a, +Float Buffer 0 -> 0.0, 1 -> 1.36E-43, +Int Buffer 0 -> 0, 1 -> 97, +Long Buffer 0 -> 97, +Short Buffer 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 97, +Double Buffer 0 -> 4.8E-322, +*///:~ diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/BufferDemo.java b/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/BufferDemo.java new file mode 100644 index 0000000..9eb1061 --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/BufferDemo.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.nio.tutorial; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +/** + * 使用Buffer的例子 + * + * @auther brian + * @since 2019/6/18 00:26 + */ +public class BufferDemo { + public static void main(String[] args) throws IOException { + String path = BufferDemo.class.getResource("/").getPath() + "buffer-demo.txt"; + RandomAccessFile aFile = new RandomAccessFile(path, "rw"); + FileChannel inChannel = aFile.getChannel(); + + //create buffer with capacity of 48 bytes + ByteBuffer buf = ByteBuffer.allocate(48); + + //read into buffer. + int bytesRead = inChannel.read(buf); + while (bytesRead != -1) { + + //make buffer ready for read + buf.flip(); + while (buf.hasRemaining()) { + // read 1 byte at a time + System.out.print((char) buf.get()); + } + + //make buffer ready for writing + // System.out.println("------"); + buf.clear(); + bytesRead = inChannel.read(buf); + } + aFile.close(); + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/ChannelDemo.java b/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/ChannelDemo.java new file mode 100644 index 0000000..18adc75 --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/ChannelDemo.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.nio.tutorial; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +/** + * 基本的 Channel 示例 + * 一个使用FileChannel读取数据到Buffer中的示例 + * + * @auther brian + * @since 2019/6/17 23:41 + */ +public class ChannelDemo { + public static void main(String[] args) { + try { + String path = ChannelDemo.class.getResource("/").getPath() + "channel-demo.txt"; + RandomAccessFile aFile = new RandomAccessFile(path, "rw"); + FileChannel inChannel = aFile.getChannel(); + // 该值小于文件内容的长度时,结果不同 + int bufferSize = 48; + ByteBuffer buf = ByteBuffer.allocate(bufferSize); + + int bytesRead = inChannel.read(buf); + while (bytesRead != -1) { + + System.out.println("Read " + bytesRead); + buf.flip(); + + while (buf.hasRemaining()) { + System.out.print((char) buf.get()); + } + + buf.clear(); + bytesRead = inChannel.read(buf); + } + aFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/SelectorDemo.java b/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/SelectorDemo.java new file mode 100644 index 0000000..99bf0a8 --- /dev/null +++ b/java-io/src/main/java/com/brianway/learning/java/nio/tutorial/SelectorDemo.java @@ -0,0 +1,64 @@ +package com.brianway.learning.java.nio.tutorial; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.util.Iterator; +import java.util.Set; + +/** + * Full Selector Example + * 启动后,浏览器输入 localhost:9999 + * + * @auther brian + * @since 2019/6/24 22:29 + */ +public class SelectorDemo { + + public static void main(String[] args) throws IOException { + Selector selector = Selector.open(); + ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); + serverSocketChannel.socket().bind(new InetSocketAddress(9999)); + serverSocketChannel.configureBlocking(false); + + // SelectionKey key = + serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); + + while (true) { + + int readyChannels = selector.selectNow(); + + if (readyChannels == 0) { + // System.out.println("readyChannels == 0"); + continue; + } + + Set selectedKeys = selector.selectedKeys(); + + Iterator keyIterator = selectedKeys.iterator(); + + while (keyIterator.hasNext()) { + + SelectionKey key = keyIterator.next(); + + if (key.isAcceptable()) { + // a connection was accepted by a ServerSocketChannel. + System.out.println("accepted"); + } else if (key.isConnectable()) { + // a connection was established with a remote server. + System.out.println("connectable"); + } else if (key.isReadable()) { + // a channel is ready for reading + System.out.println("ready"); + } else if (key.isWritable()) { + // a channel is ready for writing + System.out.println("writable"); + } + + keyIterator.remove(); + } + } + } +} diff --git a/java-io/src/main/resources/buffer-demo.txt b/java-io/src/main/resources/buffer-demo.txt new file mode 100644 index 0000000..991243a --- /dev/null +++ b/java-io/src/main/resources/buffer-demo.txt @@ -0,0 +1,20 @@ +0123456789 +asdf +123456789 +asdf +23456789 +asdf +3456789 +asdf +456789 +asdf +0123456789 +asdf +123456789 +asdf +23456789 +asdf +3456789 +asdf +456789 +asdf diff --git a/java-io/src/main/resources/channel-demo.txt b/java-io/src/main/resources/channel-demo.txt new file mode 100644 index 0000000..a4f45f9 --- /dev/null +++ b/java-io/src/main/resources/channel-demo.txt @@ -0,0 +1,2 @@ +0123456789 +asdf diff --git a/java-io/src/main/resources/infile.txt b/java-io/src/main/resources/infile.txt new file mode 100644 index 0000000..a643f77 --- /dev/null +++ b/java-io/src/main/resources/infile.txt @@ -0,0 +1,12 @@ +----------------------------------------- +public static String read(String filename) throws IOException { + BufferedReader in = new BufferedReader( + new FileReader(filename)); + String s; + StringBuilder sb = new StringBuilder(); + while ((s = in.readLine()) != null) { + sb.append(s).append("\n"); + } + in.close(); + return sb.toString(); +} \ No newline at end of file diff --git a/java-io/src/test/java/com/brianway/java/nio/tutorial/ChannelTransferTest.java b/java-io/src/test/java/com/brianway/java/nio/tutorial/ChannelTransferTest.java new file mode 100644 index 0000000..aac8b65 --- /dev/null +++ b/java-io/src/test/java/com/brianway/java/nio/tutorial/ChannelTransferTest.java @@ -0,0 +1,60 @@ +package com.brianway.java.nio.tutorial; + +import com.brianway.learning.java.nio.tutorial.BufferDemo; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; + +/** + * 通道之间的数据传输 + * + * @auther brian + * @since 2019/6/19 00:20 + */ +public class ChannelTransferTest { + private String fromPath = BufferDemo.class.getResource("/").getPath() + "fromFile.txt"; + private String toPath = BufferDemo.class.getResource("/").getPath() + "toFile.txt"; + + @Test + public void testTransferFrom() { + try { + RandomAccessFile fromFile = new RandomAccessFile(fromPath, "rw"); + FileChannel fromChannel = fromFile.getChannel(); + + RandomAccessFile toFile = new RandomAccessFile(toPath, "rw"); + FileChannel toChannel = toFile.getChannel(); + + long position = 0; + long count = fromChannel.size(); + + long transferBytesSize = + toChannel.transferFrom(fromChannel, position, count); + Assert.assertEquals(26, transferBytesSize); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Test + public void testTransferTo() { + try { + RandomAccessFile fromFile = new RandomAccessFile(fromPath, "rw"); + FileChannel fromChannel = fromFile.getChannel(); + + RandomAccessFile toFile = new RandomAccessFile(toPath, "rw"); + FileChannel toChannel = toFile.getChannel(); + + long position = 0; + long count = fromChannel.size(); + + long transferBytesSize = + fromChannel.transferTo(position, count, toChannel); + Assert.assertEquals(26, transferBytesSize); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/java-io/src/test/java/com/brianway/java/nio/tutorial/FileChannelTest.java b/java-io/src/test/java/com/brianway/java/nio/tutorial/FileChannelTest.java new file mode 100644 index 0000000..ca17f16 --- /dev/null +++ b/java-io/src/test/java/com/brianway/java/nio/tutorial/FileChannelTest.java @@ -0,0 +1,31 @@ +package com.brianway.java.nio.tutorial; + +import com.brianway.learning.java.nio.tutorial.BufferDemo; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileChannel; + +/** + * FileChannel测试 + * + * @auther brian + * @since 2019/6/24 23:00 + */ +public class FileChannelTest { + private String dir = BufferDemo.class.getResource("/").getPath(); + private String path = BufferDemo.class.getResource("/").getPath() + "fileChannel.txt"; + + @Test + public void testTruncate() throws IOException { + RandomAccessFile aFile = new RandomAccessFile(dir + "truncate.txt", "rw"); + FileChannel channel = aFile.getChannel(); + int size = 10; + // Truncates this channel's file to the given size. + channel.truncate(size); + long fileSize = channel.size(); + Assert.assertEquals(size, fileSize); + } +} diff --git a/java-io/src/test/java/com/brianway/java/nio/tutorial/GatherTest.java b/java-io/src/test/java/com/brianway/java/nio/tutorial/GatherTest.java new file mode 100644 index 0000000..5e04221 --- /dev/null +++ b/java-io/src/test/java/com/brianway/java/nio/tutorial/GatherTest.java @@ -0,0 +1,37 @@ +package com.brianway.java.nio.tutorial; + +import com.brianway.learning.java.nio.tutorial.BufferDemo; +import org.junit.Test; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; + +/** + * @auther brian + * @since 2019/6/18 23:51 + */ +public class GatherTest { + + private String path = BufferDemo.class.getResource("/").getPath() + "gather.txt"; + + @Test + public void testGatheringWrites() throws IOException { + RandomAccessFile aFile = new RandomAccessFile(path, "rw"); + FileChannel channel = aFile.getChannel(); + ByteBuffer header = ByteBuffer.allocate(128); + ByteBuffer body = ByteBuffer.allocate(1024); + + header.put("这是头".getBytes(Charset.forName("UTF-8"))); + body.put("this is body.".getBytes(Charset.forName("UTF-8"))); + header.flip(); + body.flip(); + //write data into buffers + ByteBuffer[] bufferArray = {header, body}; + // 注意只有position和limit之间的数据才会被写入 + channel.write(bufferArray); + channel.close(); + } +} diff --git a/java-io/src/test/java/com/brianway/java/nio/tutorial/ScatterTest.java b/java-io/src/test/java/com/brianway/java/nio/tutorial/ScatterTest.java new file mode 100644 index 0000000..a02ddbf --- /dev/null +++ b/java-io/src/test/java/com/brianway/java/nio/tutorial/ScatterTest.java @@ -0,0 +1,53 @@ +package com.brianway.java.nio.tutorial; + +import com.brianway.learning.java.nio.tutorial.BufferDemo; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +/** + * @auther brian + * @since 2019/6/18 23:24 + */ +public class ScatterTest { + + private String path = BufferDemo.class.getResource("/").getPath() + "scatter.txt"; + + @Test + public void testScatteringReads() throws IOException { + RandomAccessFile aFile = new RandomAccessFile(path, "rw"); + FileChannel fc = aFile.getChannel(); + + //create buffer with capacity of 48 bytes + ByteBuffer header = ByteBuffer.allocate(8); + ByteBuffer body = ByteBuffer.allocate(1024); + + ByteBuffer[] bufferArray = {header, body}; + long bytesRead = fc.read(bufferArray); + // System.out.println(bytesRead); + Assert.assertEquals(26, bytesRead); + //print header + System.out.println("---header(" + header.limit() + "bytes)---"); + header.flip(); + while (header.hasRemaining()) { + // read 1 byte at a time + System.out.print((char) header.get()); + } + header.clear(); + + // print body + body.flip(); + System.out.println("---body(" + body.limit() + "bytes)----"); + while (body.hasRemaining()) { + // read 1 byte at a time + System.out.print((char) body.get()); + } + header.clear(); + body.clear(); + fc.close(); + } +} diff --git a/java-io/src/test/java/com/brianway/java/nio/tutorial/ServerSocketChannelTest.java b/java-io/src/test/java/com/brianway/java/nio/tutorial/ServerSocketChannelTest.java new file mode 100644 index 0000000..30ed0f1 --- /dev/null +++ b/java-io/src/test/java/com/brianway/java/nio/tutorial/ServerSocketChannelTest.java @@ -0,0 +1,48 @@ +package com.brianway.java.nio.tutorial; + +import org.junit.Test; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +/** + * @auther brian + * @since 2019/6/25 00:31 + */ +public class ServerSocketChannelTest { + + @Test + public void testOpen() throws IOException { + ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); + serverSocketChannel.socket().bind(new InetSocketAddress(9999)); + while (true) { + System.out.println("waiting..."); + SocketChannel socketChannel = + serverSocketChannel.accept(); + //do something with socketChannel... + System.out.println("connected: " + socketChannel.toString()); + } + } + + @Test + public void testNonBlocking() throws IOException { + ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); + + serverSocketChannel.socket().bind(new InetSocketAddress(9999)); + serverSocketChannel.configureBlocking(false); + + while (true) { + System.out.println("waiting..."); + SocketChannel socketChannel = + serverSocketChannel.accept(); + + if (socketChannel != null) { + //do something with socketChannel... + System.out.println("connected: " + socketChannel.toString()); + } + } + } + +} diff --git a/java-io/src/test/java/com/brianway/java/nio/tutorial/SocketChannelTest.java b/java-io/src/test/java/com/brianway/java/nio/tutorial/SocketChannelTest.java new file mode 100644 index 0000000..3146572 --- /dev/null +++ b/java-io/src/test/java/com/brianway/java/nio/tutorial/SocketChannelTest.java @@ -0,0 +1,37 @@ +package com.brianway.java.nio.tutorial; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.SocketChannel; + +/** + * @auther brian + * @since 2019/6/24 23:33 + */ +public class SocketChannelTest { + + @Test + public void testConnect() throws IOException { + SocketChannel socketChannel = SocketChannel.open(); + boolean connected = socketChannel.connect(new InetSocketAddress("www.baidu.com", 80)); + Assert.assertEquals(true, connected); + socketChannel.close(); + } + + @Test + public void testNonBlocking() throws IOException { + SocketChannel socketChannel = SocketChannel.open(); + socketChannel.configureBlocking(false); + boolean connected = socketChannel.connect(new InetSocketAddress("www.baidu.com", 80)); + System.out.println("connected: " + connected); + while (!socketChannel.finishConnect()) { + //wait, or do something else... + System.out.println("not finish"); + } + System.out.println("finished"); + } + +} diff --git a/java-io/src/test/resources/fileChannel.txt b/java-io/src/test/resources/fileChannel.txt new file mode 100644 index 0000000..32ca54f --- /dev/null +++ b/java-io/src/test/resources/fileChannel.txt @@ -0,0 +1,4 @@ +asdasdas +ahfsadkjhsdfkjl +23232323 +2323 \ No newline at end of file diff --git a/java-io/src/test/resources/fromFile.txt b/java-io/src/test/resources/fromFile.txt new file mode 100644 index 0000000..dbd2aa4 --- /dev/null +++ b/java-io/src/test/resources/fromFile.txt @@ -0,0 +1,3 @@ +1234567 +qwertyusfdf +asdsad \ No newline at end of file diff --git a/java-io/src/test/resources/scatter.txt b/java-io/src/test/resources/scatter.txt new file mode 100644 index 0000000..dbd2aa4 --- /dev/null +++ b/java-io/src/test/resources/scatter.txt @@ -0,0 +1,3 @@ +1234567 +qwertyusfdf +asdsad \ No newline at end of file diff --git a/java-io/src/test/resources/truncate.txt b/java-io/src/test/resources/truncate.txt new file mode 100644 index 0000000..32ca54f --- /dev/null +++ b/java-io/src/test/resources/truncate.txt @@ -0,0 +1,4 @@ +asdasdas +ahfsadkjhsdfkjl +23232323 +2323 \ No newline at end of file diff --git a/java-jvm/pom.xml b/java-jvm/pom.xml new file mode 100644 index 0000000..0df23ec --- /dev/null +++ b/java-jvm/pom.xml @@ -0,0 +1,14 @@ + + + + java-learning + com.brianway.learning.java + 1.0-SNAPSHOT + + 4.0.0 + + java-jvm + + \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ClassLoaderTest.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ClassLoaderTest.java new file mode 100644 index 0000000..6c6c289 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ClassLoaderTest.java @@ -0,0 +1,40 @@ +package com.brianway.learning.java.jvm.classloading; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Created by brian on 17/3/20. + * 不同的类加载器对 instanceof 关键字运算结果的影响 + */ +public class ClassLoaderTest { + public static void main(String[] args) throws Exception { + ClassLoader myLoader = new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + try { + String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class"; + + InputStream is = getClass().getResourceAsStream(fileName); + if (is == null) { + return super.loadClass(name); + } + byte[] b = new byte[is.available()]; + is.read(b); + return defineClass(name, b, 0, b.length); + } catch (IOException e) { + throw new ClassNotFoundException(name); + } + } + }; + + Object obj = myLoader.loadClass("com.brianway.learning.java.jvm.classloading.ClassLoaderTest").newInstance(); + System.out.println(obj.getClass()); + System.out.println(obj instanceof com.brianway.learning.java.jvm.classloading.ClassLoaderTest); + } +} + +/* +class com.brianway.learning.java.jvm.classloading.ClassLoaderTest +false + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ClinitOrder.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ClinitOrder.java new file mode 100644 index 0000000..365a2e7 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ClinitOrder.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/20. + * () 方法执行顺序 + */ +public class ClinitOrder { + static class Parent { + public static int A = 1; + + static { + System.out.println("execute before A = 2, A now is " + A); + A = 2; + } + } + + static class Sub extends Parent { + public static int B = A; + } + + + public static void main(String[] args) { + System.out.println(Sub.B); + } +} + + diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ConstClass.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ConstClass.java new file mode 100644 index 0000000..9338623 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/ConstClass.java @@ -0,0 +1,15 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/19. + * 被动使用类字段演示 + * 常量在编译阶段会存入调用类的常量池,本质上没有引用调用常量的类, + * 不会触发定义常量的类的初始化 + */ +public class ConstClass { + static { + System.out.println("ConsClass init!"); + } + + public static final String HELLOWORLD = "hello world"; +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/DeadLoopClass.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/DeadLoopClass.java new file mode 100644 index 0000000..f2ec554 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/DeadLoopClass.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/20. + * 字段解析 + * 多个线程同时初始化一个类,只有一个线程会执行 ()方法,其他被阻塞 + */ +public class DeadLoopClass { + static { + if (true) { + System.out.println(Thread.currentThread() + " init DeadLoopClass"); + while (true) { + + } + } + } + + public static void main(String[] args) { + Runnable script = () -> { + System.out.println(Thread.currentThread() + " start"); + DeadLoopClass dlc = new DeadLoopClass(); + System.out.println(Thread.currentThread() + " run over"); + }; + + Thread thread1 = new Thread(script); + Thread thread2 = new Thread(script); + thread1.start(); + thread2.start(); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/FieldResolution.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/FieldResolution.java new file mode 100644 index 0000000..04ecfdb --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/FieldResolution.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/20. + * 字段解析 + * 如果注释了 Sub 类中的 "public static int A = 4",会编译错误 + */ +public class FieldResolution { + interface Interface0 { + int A = 0; + } + + interface Interface1 extends Interface0 { + int A = 1; + } + + interface Interface2 { + int A = 2; + } + + static class Parent implements Interface1 { + public static int A = 3; + } + + static class Sub extends Parent implements Interface2 { + public static int A = 4;// 注释此句试试 + } + + public static void main(String[] args) { + System.out.println(Sub.A); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/NoInitialization.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/NoInitialization.java new file mode 100644 index 0000000..4efbf0f --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/NoInitialization.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/19. + * 非主动使用类字段演示 + * 1. 静态字段只有直接定义这个字段的类才会被初始化 + * 2. 通过数组来定义引用类,不会触发类的初始化 + * (-XX:+TraceClassLoading,对于 HotSpot 虚拟机可观察到子类的加载) + */ +public class NoInitialization { + public static void main(String[] args) { + System.out.println(SubClass.value); + SubClass[] sca = new SubClass[10]; + + System.out.println(ConstClass.HELLOWORLD); + } +} +/* +SuperClass init! +123 + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SimpleClass.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SimpleClass.java new file mode 100644 index 0000000..fc00360 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SimpleClass.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/15. + * 一段简单的 Java 代码,用于分析字节码 + * javap -verbose SimpleClass.java + */ +public class SimpleClass { + private int m; + + public int inc() { + return m + 1; + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SubClass.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SubClass.java new file mode 100644 index 0000000..a15c620 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SubClass.java @@ -0,0 +1,10 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/19. + */ +public class SubClass extends SuperClass { + static { + System.out.println("SubClass init!"); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SuperClass.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SuperClass.java new file mode 100644 index 0000000..6b83c5c --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/classloading/SuperClass.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.jvm.classloading; + +/** + * Created by brian on 17/3/19. + * 被动引用的例子 + * 通过子类引用父类的静态字段,不会导致子类初始化 + */ +public class SuperClass { + static { + System.out.println("SuperClass init!"); + } + + public static int value = 123; +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/GrandFatherCaller.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/GrandFatherCaller.java new file mode 100644 index 0000000..5c5fa41 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/GrandFatherCaller.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.jvm.dynamictype; + +import static java.lang.invoke.MethodHandles.lookup; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +/** + * Created by brian on 17/3/20. + * 使用 MethodHandle 来访问祖类方法 + * TODO 为什么打印出来的是 "i am father" 而不是 "i am grandfather"? + * 参考: + * https://www.zhihu.com/question/57379777 + * https://www.zhihu.com/question/40427344/answer/86545388 + */ +public class GrandFatherCaller { + class GrandFather { + void thinking() { + System.out.println("i am grandfather"); + } + } + + class Father extends GrandFather { + void thinking() { + System.out.println("i am father"); + } + } + + class Son extends Father { + void thinking() { + try { + MethodType mt = MethodType.methodType(void.class); + MethodHandle mh = lookup().findSpecial( + GrandFather.class, "thinking", mt, Son.class); + mh.invoke(this); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + } + + public static void main(String[] args) { + (new GrandFatherCaller().new Son()).thinking(); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/InvokeDynamicTest.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/InvokeDynamicTest.java new file mode 100644 index 0000000..5d5fb01 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/InvokeDynamicTest.java @@ -0,0 +1,53 @@ +package com.brianway.learning.java.jvm.dynamictype; + +import static java.lang.invoke.MethodHandles.lookup; + +import java.lang.invoke.CallSite; +import java.lang.invoke.ConstantCallSite; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +/** + * Created by brian on 17/3/20. + * invokedynamic 指令演示 + */ +public class InvokeDynamicTest { + + public static void main(String[] args) throws Throwable { + INDY_BootstrapMethod().invokeExact("brianway"); + } + + public static void testMethod(String s) { + System.out.println("hello String:" + s); + } + + public static CallSite BootstrapMethod( + MethodHandles.Lookup lookup, String name, MethodType mt) + throws Throwable { + return new ConstantCallSite(lookup.findStatic(InvokeDynamicTest.class, name, mt)); + } + + private static MethodType MT_BootstrapMethod() { + return MethodType.fromMethodDescriptorString( + "(Ljava/lang/invoke/MethodHandles$Lookup;" + + "Ljava/lang/String;Ljava/lang/invoke/MethodType;)" + + "Ljava/lang/invoke/CallSite;", null + ); + } + + private static MethodHandle MH_BootstrapMethod() throws Throwable { + return lookup().findStatic(InvokeDynamicTest.class, "BootstrapMethod", + MT_BootstrapMethod()); + } + + private static MethodHandle INDY_BootstrapMethod() throws Throwable { + CallSite cs = (CallSite) MH_BootstrapMethod().invokeWithArguments( + lookup(), + "testMethod", + MethodType.fromMethodDescriptorString( + "(Ljava/lang/String;)V", null + )); + return cs.dynamicInvoker(); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/MethodHandleTest.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/MethodHandleTest.java new file mode 100644 index 0000000..0d977a5 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/dynamictype/MethodHandleTest.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java.jvm.dynamictype; + +import static java.lang.invoke.MethodHandles.lookup; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; + +/** + * Created by brian on 17/3/20. + * MethodHandle 演示 + */ +public class MethodHandleTest { + static class ClassA { + public void println(String s) { + System.out.println("classA " + s); + } + } + + public static void main(String[] args) throws Throwable { + Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); + getPrintlnMH(obj).invokeExact("brianway"); + } + + private static MethodHandle getPrintlnMH(Object receiver) throws Throwable { + // 方法类型 + MethodType mt = MethodType.methodType(void.class, String.class); + + return lookup().findVirtual(receiver.getClass(), "println", mt) + .bindTo(receiver); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/gc/FinalizeEscapeGC.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/gc/FinalizeEscapeGC.java new file mode 100644 index 0000000..810caf1 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/gc/FinalizeEscapeGC.java @@ -0,0 +1,58 @@ +package com.brianway.learning.java.jvm.gc; + +/** + * Created by brian on 17/3/3. + * 对象可以在被 GC 时自我拯救 + * 这种自救的机会只有一次,因为一个对象的 finalize() 方法最多只会被系统自动调用一次 + */ +public class FinalizeEscapeGC { + public static FinalizeEscapeGC SAVE_HOOK = null; + + public void isAlive() { + System.out.println("yes, i am still alive :)"); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + System.out.println("finalize method executed"); + FinalizeEscapeGC.SAVE_HOOK = this; + } + + public static void main(String[] args) throws Throwable { + SAVE_HOOK = new FinalizeEscapeGC(); + + //对象第一次成功拯救自己 + SAVE_HOOK = null; + System.gc(); + + // finalize 优先级低,暂停 0.5 秒以等待 + Thread.sleep(500); + + if (SAVE_HOOK != null) { + SAVE_HOOK.isAlive(); + } else { + System.out.println("no, i ma dead :("); + } + + //与上面完全相同,缺失败 + SAVE_HOOK = null; + System.gc(); + + // finalize 优先级低,暂停 0.5 秒以等待 + Thread.sleep(500); + + if (SAVE_HOOK != null) { + SAVE_HOOK.isAlive(); + } else { + System.out.println("no, i ma dead :("); + } + + } +} + +/* +finalize method executed +yes, i am still alive :) +no, i ma dead :( + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/gc/ReferenceCountingGC.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/gc/ReferenceCountingGC.java new file mode 100644 index 0000000..2f15e09 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/gc/ReferenceCountingGC.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java.jvm.gc; + +/** + * Created by brian on 17/3/2. + * 引用计数算法缺陷 + */ +public class ReferenceCountingGC { + public Object instance = null; + private static final int _1MB = 1024 * 1024; + + /** + * 占点内存,以便 GC 日志观看 + */ + private byte[] bigSize = new byte[2 * _1MB]; + + public static void main(String[] args) { + testGC(); + } + + public static void testGC() { + ReferenceCountingGC objA = new ReferenceCountingGC(); + ReferenceCountingGC objB = new ReferenceCountingGC(); + objA.instance = objB; + objB.instance = objA; + + objA = null; + objB = null; + + System.gc(); + } +} diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/DirectMemoryOOM.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/DirectMemoryOOM.java new file mode 100644 index 0000000..a11b090 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/DirectMemoryOOM.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.jvm.memory; + +import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +/** + * Created by brian on 17/3/2. + * 使用 unsafe 分配本机内存 + * VM Args: -Xmx20M -XX:MaxDirectMemorySize=10M + */ +public class DirectMemoryOOM { + private static final int _1MB = 1024 * 1024; + + public static void main(String[] args) throws Exception { + Field unsafeField = Unsafe.class.getDeclaredFields()[0]; + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe) unsafeField.get(null); + + while (true) { + unsafe.allocateMemory(_1MB); + } + } +} + +/* +TODO 没出现 OOM + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/HeapOOM.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/HeapOOM.java new file mode 100644 index 0000000..ecd759a --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/HeapOOM.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.jvm.memory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by brian on 17/3/1. + * Java 堆内存溢出异常测试 + * VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError + * (限制堆大小为 20 MB) + */ +public class HeapOOM { + static class OOMObject { + } + + public static void main(String[] args) { + List list = new ArrayList<>(); + + while (true) { + list.add(new OOMObject()); + } + } + +} + +/* +java.lang.OutOfMemoryError: Java heap space +Dumping heap to java_pid25599.hprof ... +Heap dump file created [27802397 bytes in 0.106 secs] +Exception in thread "main" java.lang.OutOfMemoryError: Java heap space + at java.util.Arrays.copyOf(Arrays.java:3210) + at java.util.Arrays.copyOf(Arrays.java:3181) + at java.util.ArrayList.grow(ArrayList.java:261) + at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235) + at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227) + at java.util.ArrayList.add(ArrayList.java:458) + at com.brianway.learning.java.jvm.memory.HeapOOM.main(HeapOOM.java:19) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) + +Process finished with exit code 1 + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/JavaVMStackOOM.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/JavaVMStackOOM.java new file mode 100644 index 0000000..30b933b --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/JavaVMStackOOM.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.jvm.memory; + +/** + * Created by brian on 17/3/1. + * 创建线程导致内存溢出异常 + * VM Args: -Xss2M + */ +public class JavaVMStackOOM { + private void dontStop() { + while (true) { + } + } + + public void stackLeakByThread() { + while (true) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + dontStop(); + } + }); + thread.start(); + } + } + + public static void main(String[] args) { + JavaVMStackOOM oom = new JavaVMStackOOM(); + oom.stackLeakByThread(); + } +} + +/* +Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated +Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread + at java.lang.Thread.start0(Native Method) + at java.lang.Thread.start(Thread.java:714) + at com.brianway.learning.java.jvm.memory.JavaVMStackOOM.stackLeakByThread(JavaVMStackOOM.java:22) + at com.brianway.learning.java.jvm.memory.JavaVMStackOOM.main(JavaVMStackOOM.java:28) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) + + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/JavaVMStackSOF.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/JavaVMStackSOF.java new file mode 100644 index 0000000..d42fed6 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/JavaVMStackSOF.java @@ -0,0 +1,50 @@ +package com.brianway.learning.java.jvm.memory; + +/** + * Created by brian on 17/3/1. + * 虚拟机栈和本地方法栈 OOM 测试 + * VM Args: -Xss256k + */ +public class JavaVMStackSOF { + private int stackLength = 1; + + public void stackLeak() { + stackLength++; + stackLeak(); + } + + public static void main(String[] args) { + JavaVMStackSOF oom = new JavaVMStackSOF(); + + try { + oom.stackLeak(); + } catch (Throwable e) { + System.out.println("stack length:" + oom.stackLength); + throw e; + } + } + +} + +/* +stack length:1862 +Exception in thread "main" java.lang.StackOverflowError + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + at com.brianway.learning.java.jvm.memory.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) + + ..... + + + +Process finished with exit code 1 + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/RuntimeConstantPoolOOM.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/RuntimeConstantPoolOOM.java new file mode 100644 index 0000000..e206aa6 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/memory/RuntimeConstantPoolOOM.java @@ -0,0 +1,48 @@ +package com.brianway.learning.java.jvm.memory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by brian on 17/3/2. + * 运行时常量池导致的内存溢出异常 + * VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M + * + * 这两个配置项在 JDK 1.8 已经不支持了 + */ +public class RuntimeConstantPoolOOM { + public static void main(String[] args) { + + testEqual(); + + //使用 List 保持着常量引用,避免被 Full GC 回收常量池行为 + List list = new ArrayList<>(); + + //10MB 的 PermSize 在 integer 范围内足够产生 OOM 了 + int i = 0; + while (true) { + list.add(String.valueOf(i++).intern()); + } + } + + /** + * JDK 1.8 + * true + * false + * intern()不会再复制实例,只是在常量池中记录首次出现的实例引用 + */ + private static void testEqual(){ + String str1 = new StringBuilder("计算机").append("软件").toString(); + System.out.println(str1.intern() == str1);// true + + String str2 = new StringBuilder("ja").append("va").toString(); + System.out.println(str2.intern() == str2);// false + } +} + + + +/* +Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=10M; support was removed in 8.0 +Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=10M; support was removed in 8.0 + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/Dispatch.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/Dispatch.java new file mode 100644 index 0000000..ffb9f59 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/Dispatch.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.jvm.methodinvoke; + +/** + * Created by brian on 17/3/20. + * 单分派、多分派演示 + */ +public class Dispatch { + static class QQ { + } + + static class _360 { + } + + public static class Father { + public void hardChoice(QQ arg) { + System.out.println("father choose qq"); + } + + public void hardChoice(_360 arg) { + System.out.println("father choose 360"); + } + } + + public static class Son extends Father { + public void hardChoice(QQ arg) { + System.out.println("son choose qq"); + } + + public void hardChoice(_360 arg) { + System.out.println("son choose 360"); + } + } + + public static void main(String[] args) { + Father father = new Father(); + Father son = new Son(); + father.hardChoice(new _360()); + son.hardChoice(new QQ()); + } +} + +/* +father choose 360 +son choose qq + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/DynamicDispatch.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/DynamicDispatch.java new file mode 100644 index 0000000..1088fa3 --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/DynamicDispatch.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.jvm.methodinvoke; + +/** + * Created by brian on 17/3/20. + * 方法动态分派演示 + */ +public class DynamicDispatch { + static abstract class Human { + protected abstract void sayHello(); + } + + static class Man extends Human { + @Override + protected void sayHello() { + System.out.println("man say hello"); + } + } + + static class Woman extends Human { + @Override + protected void sayHello() { + System.out.println("woman say hello"); + } + } + + public static void main(String[] args) { + Human man = new Man(); + Human woman = new Woman(); + man.sayHello(); + woman.sayHello(); + + man = new Woman(); + man.sayHello(); + } +} + +/* +man say hello +woman say hello +woman say hello + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/StaticDispatch.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/StaticDispatch.java new file mode 100644 index 0000000..c0b644f --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/StaticDispatch.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.jvm.methodinvoke; + +/** + * Created by brian on 17/3/20. + * 方法静态分派演示 + * Method Overload Resolution + */ +public class StaticDispatch { + static abstract class Human { + } + + static class Man extends Human { + } + + static class Woman extends Human { + } + + public void sayHello(Human guy) { + System.out.println("hello,guy!"); + } + + public void sayHello(Man guy) { + System.out.println("hello,gentleman!"); + } + + public void sayHello(Woman guy) { + System.out.println("hello,lady!"); + } + + public static void main(String[] args) { + Human man = new Man(); + Human woman = new Woman(); + StaticDispatch sr = new StaticDispatch(); + + sr.sayHello(man); + sr.sayHello(woman); + sr.sayHello((Man)man); + sr.sayHello((Woman) woman); + } +} + +/* +hello,guy! +hello,guy! +hello,gentleman! +hello,lady! + */ \ No newline at end of file diff --git a/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/StaticResolution.java b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/StaticResolution.java new file mode 100644 index 0000000..c5df56e --- /dev/null +++ b/java-jvm/src/main/java/com/brianway/learning/java/jvm/methodinvoke/StaticResolution.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.jvm.methodinvoke; + +/** + * Created by brian on 17/3/20. + * 方法静态解析演示 + * javac -verbose StaticResolution.java + * javap -verbose StaticResolution + */ +public class StaticResolution { + public static void sayHello() { + System.out.println("hello world"); + } + + public static void main(String[] args) { + StaticResolution.sayHello(); + } +} diff --git a/java-multithread/README.md b/java-multithread/README.md new file mode 100644 index 0000000..8380e61 --- /dev/null +++ b/java-multithread/README.md @@ -0,0 +1,248 @@ +# 多线程模块 + +知识点的文字梳理请参考这篇文章:[java多线程核心技术梳理](http://blog.csdn.net/h3243212/article/details/51180173) + +下面对该模块的几个包作说明: + +## meet + +该部分是一些简单的基础知识的展示 + +- [printMain.java](src/main/java/com/brianway/learning/java/multithread/meet/printMain.java):打印当前线程名称 +- [Run.java](src/main/java/com/brianway/learning/java/multithread/meet/Run.java):非线程安全的数据共享 +- [Run2_StartVsRun.java](src/main/java/com/brianway/learning/java/multithread/meet/Run2_StartVsRun.java):`run()` 和 `start()` 的区别 +- [Run3_getName.java](src/main/java/com/brianway/learning/java/multithread/meet/Run3_getName.java):`this.getName()!=Thread.currentThread().getName()`,这是两个概念 +- [Run4_isAlive01.java](src/main/java/com/brianway/learning/java/multithread/meet/Run4_isAlive01.java):`isAlive()` +- [Run5_isAlive02.java](src/main/java/com/brianway/learning/java/multithread/meet/Run5_isAlive02.java):`isAlive()` +- [Run6_StartVsRun02.java](src/main/java/com/brianway/learning/java/multithread/meet/Run6_StartVsRun02.java):`run()` 同步执行,`start()` 异步执行 +- [Run7_interrupt01.java](src/main/java/com/brianway/learning/java/multithread/meet/Run7_interrupt01.java):停止线程 +- [Run8_interrupted01.java](src/main/java/com/brianway/learning/java/multithread/meet/Run8_interrupted01.java):判断线程是否停止状态,测试当前线程是否已经中断 +- [Run9_interrupted02.java](src/main/java/com/brianway/learning/java/multithread/meet/Run9_interrupted02.java):线程的中断状态由 `interrupted()` 清除 +- [Run10_isInterrupted.java](src/main/java/com/brianway/learning/java/multithread/meet/Run10_isInterrupted.java):`isInterrupted()`,不清除状态标记 +- [Run11_sleepAndinterrupt01.java](src/main/java/com/brianway/learning/java/multithread/meet/Run11_sleepAndinterrupt01.java):睡眠中停止,先进入的 `sleep()`,再 `interrupt()` +- [Run12_sleepAndinterrupt02.java](src/main/java/com/brianway/learning/java/multithread/meet/Run12_sleepAndinterrupt02.java):先 `interrupt()`,再进入 `sleep()`,直接进异常 +- [Run13_suspendAndresume01.java](src/main/java/com/brianway/learning/java/multithread/meet/Run13_suspendAndresume01.java):暂停线程,`suspend()` 与 `resume()` +- [Run14_suspendAndresume02.java](src/main/java/com/brianway/learning/java/multithread/meet/Run14_suspendAndresume02.java):`suspend()` 与 `resume()` 的缺点:独占 +- [Run15_suspendAndresume03.java](src/main/java/com/brianway/learning/java/multithread/meet/Run15_suspendAndresume03.java):`suspend()` 独占锁问题,`println()` +- [Run16_yield.java](src/main/java/com/brianway/learning/java/multithread/meet/Run16_yield.java):测试 `yield()` +- [Run17_priority01.java](src/main/java/com/brianway/learning/java/multithread/meet/Run17_priority01.java):线程优先级的继承性 +- [Run18_priority02.java](src/main/java/com/brianway/learning/java/multithread/meet/Run18_priority02.java):优先级具有规则性 + +## synchronize + +- [example1](src/main/java/com/brianway/learning/java/multithread/synchronize/example1) + - [Run1_local.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example1/Run1_local.java):方法内局部变量则不存在“非线程安全”问题 +- [example2](src/main/java/com/brianway/learning/java/multithread/synchronize/example2) + - [Run2_private01.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_private01.java):实例变量非线程安全 + - [Run2_twoObject.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_twoObject.java):多个对象多个锁 +- [example3](src/main/java/com/brianway/learning/java/multithread/synchronize/example3) + - [Run3_synchronized01.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example3/Run3_synchronized01.java):`synchronized` 方法与锁对象 +- [example4](src/main/java/com/brianway/learning/java/multithread/synchronize/example4) + - [Run4_synchronized01.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example4/Run4_synchronized01.java):两个线程访问同一个对象的不同方法,线程 B 可异步调用非 `synchronized` 类型方法 +- [example5](src/main/java/com/brianway/learning/java/multithread/synchronize/example5) + - [Run5_lockRein.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Run5_lockRein.java):`synchronized` 锁重入,支持继承 +- [example6](src/main/java/com/brianway/learning/java/multithread/synchronize/example6) + - [Run6_exception.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Run6_exception.java):出现异常,锁自动释放 +- [example7](src/main/java/com/brianway/learning/java/multithread/synchronize/example7) + - [Run7_synNotExtends.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Run7_synNotExtends.java):同步不具继承性 +- [example8](src/main/java/com/brianway/learning/java/multithread/synchronize/example8) + - [Run8_synchronized01.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized01.java):`synchronized` 方法的弊端 + - [Run8_synchronized02.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized02.java):同步代码块解决同步方法的弊端 +- [example9](src/main/java/com/brianway/learning/java/multithread/synchronize/example9) + - [Run9_synchronized01.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01.java):当多个线程同时执行`synchronized(x){}`同步代码块时呈现效果 + - [Run9_synchronized01_twoObjects.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01_twoObjects.java):不同的“对象监视器” + - [Run9_synchronized02.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized02.java):当其他线程执行 x 对象中 `synchronized` 同步方法时呈同步效果 + - [Run9_synchronized03.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized03.java):当其他线程执行 x 对象里面的`synchronized(this)`代码块时,也呈现同步效果 +- [example10](src/main/java/com/brianway/learning/java/multithread/synchronize/example10) + - [Run10_synBlockMoreObjectOneLock.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synBlockMoreObjectOneLock.java):验证同步 `synchronized(class)` 代码块的作用 + - [Run10_synMoreObjectStaticOneLock.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synMoreObjectStaticOneLock.java):Class 锁可以对类的所有对象实例起作用 + - [Run10_synTwoLock.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synTwoLock.java):验证 `synchronized` 关键字加载 `static` 静态方法和加到非静态方法不是同一个锁 +- [example11](src/main/java/com/brianway/learning/java/multithread/synchronize/example11) + - [Run11_StringAndSyn.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn.java):String 作为锁对象,常量池->同一锁 + - [Run11_StringAndSyn2.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn2.java):不使用 String 作为锁对象 +- [example12](src/main/java/com/brianway/learning/java/multithread/synchronize/example12) + - [Run12_deadLock.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example12/Run12_deadLock.java):死锁测试,jstack命令 +- [example13](src/main/java/com/brianway/learning/java/multithread/synchronize/example13) + - [Run13_inner01.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java):内置类和同步测试1 + - [Run13_inner02.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java):内置类与同步测试2 +- [example14](src/main/java/com/brianway/learning/java/multithread/synchronize/example14) + - [Run14_setNewStringTwoLock.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Run14_setNewStringTwoLock.java):锁对象改变 +- [example15](src/main/java/com/brianway/learning/java/multithread/synchronize/example15) + - [Run15_synchronized.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_synchronized.java):`synchronized` 代码块有 `volatile` 同步的功能 + - [Run15_volatile.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_volatile.java):不使用 `volatile` 关键字,JVM 配置 `-server` +- [example16](src/main/java/com/brianway/learning/java/multithread/synchronize/example16) + - [Run16_volatile.java](src/main/java/com/brianway/learning/java/multithread/synchronize/example16/Run16_volatile.java):`volatile` 非原子的特性 + + + +## communication + +- [example1](src/main/java/com/brianway/learning/java/multithread/communication/example1) + - [Run1_TwoThreadTransData.java](src/main/java/com/brianway/learning/java/multithread/communication/example1/Run1_TwoThreadTransData.java):不使用等待/通知机制实现线程间通 +- [example2](src/main/java/com/brianway/learning/java/multithread/communication/example2) + - [Run2_noObjectLock.java](src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_noObjectLock.java):没有“对象监视器”,调用 `wait()` 方法出现运行时异常 + - [Run2_notify.java](src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_notify.java):`notify` 实现通知,`notify` 调用后,并不会立即释放对象锁,而是退出 `synchronized` 代码块后 + - [Run2_sleep.java](src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_sleep.java):测试 `sleep()` 期间其他线程是否执行 + - [Run2_wait.java](src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_wait.java):`wait()` 永远阻塞 +- [example3](src/main/java/com/brianway/learning/java/multithread/communication/example3) + - [Run3_notifyAll.java](src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyAll.java):唤醒多个线程 + - [Run3_notifyMany.java](src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyMany.java):通知多个线程 + - [Run3_notifyOne.java](src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyOne.java):通知一个线程 +- [example4](src/main/java/com/brianway/learning/java/multithread/communication/example4) + - [Run4_waitHasParam.java](src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam.java):`wait(long)` 使用,超时自动唤醒 + - [Run4_waitHasParam2.java](src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam2.java):`wait(long)` 使用,时间限制内由其他线程唤醒 +- [example5](src/main/java/com/brianway/learning/java/multithread/communication/example5) + - [Run5_notify.java](src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notify.java):`notify` 正常通知 + - [Run5_notifyEarly.java](src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notifyEarly.java):`notify` 通知过早 +- [example6](src/main/java/com/brianway/learning/java/multithread/communication/example6) + - [Run6_waitOld.java](src/main/java/com/brianway/learning/java/multithread/communication/example6/Run6_waitOld.java):`wait` 等待条件变化 +- [example7](src/main/java/com/brianway/learning/java/multithread/communication/example7) + - [Run7_ProducerAndConsumer_One.java](src/main/java/com/brianway/learning/java/multithread/communication/example7/Run7_ProducerAndConsumer_One.java):生产者/消费者模式,一生产一消费 +- [example8](src/main/java/com/brianway/learning/java/multithread/communication/example8) + - [Run8_allWait.java](src/main/java/com/brianway/learning/java/multithread/communication/example8/Run8_allWait.java):多生产与多消费,假死 +- [example9](src/main/java/com/brianway/learning/java/multithread/communication/example9) + - [Run9_oneP_manyC.java](src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_manyC.java):一生产与多消费 + - [Run9_oneP_oneC.java](src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_oneC.java):一生产与一消费 +- [example10](src/main/java/com/brianway/learning/java/multithread/communication/example10) + - [Run10_oneP_manyC.java](src/main/java/com/brianway/learning/java/multithread/communication/example10/Run10_oneP_manyC.java):一生产与多消费 +- [example11](src/main/java/com/brianway/learning/java/multithread/communication/example11) + - [Run11_manyP_manyC.java](src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_manyC.java):多生产与多消费 + - [Run11_manyP_oneC.java](src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_oneC.java):多生产与一消费 + - [Run11_oneP_manyC.java](src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_oneP_manyC.java):一生产与多消费 +- [example12](src/main/java/com/brianway/learning/java/multithread/communication/example12) + - [Run12_pipeInputOutput.java](src/main/java/com/brianway/learning/java/multithread/communication/example12/Run12_pipeInputOutput.java):通过管道进行线程间通信:字节流 +- [example13](src/main/java/com/brianway/learning/java/multithread/communication/example13) + - [Run13_wait_notify_insert.java](src/main/java/com/brianway/learning/java/multithread/communication/example13/Run13_wait_notify_insert.java):等待/通知,交叉执行 +- [example14](src/main/java/com/brianway/learning/java/multithread/communication/example14) + - [Run14_join.java](src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_join.java):`join` 示例 + - [Run14_joinExption.java](src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinExption.java):`join` 的异常 + - [Run14_joinLong.java](src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinLong.java):`join(long)` 设定等待的时间,`join(long)` 和 `sleep(long)` 运行效果并无区别,但对同步的处理不同 +- [example15](src/main/java/com/brianway/learning/java/multithread/communication/example15) + - [Run15_join_sleep.java](src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep.java):`join(long)` 和 `sleep(long)` 的区别,`sleep(long)` 方法不释放锁 + - [Run15_join_sleep_2.java](src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep_2.java):`join(long)` 和 `sleep(long)` 的区别,`join(long)` 释放锁 + - [Run15_joinMore.java](src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_joinMore.java):方法 `join` 后面的代码提前运行 +- [example16](src/main/java/com/brianway/learning/java/multithread/communication/example16) + - [Run16_InheritableThreadLocalExt.java](src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt.java):类 `InheritableThreadLocal` 使用,值继承,子线程从父线程取得值 + - [Run16_InheritableThreadLocalExt2.java](src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt2.java):类 `InheritableThreadLocal` 使用,值继承再更改 + - [Run16_ThreadLocal.java](src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_ThreadLocal.java):验证线程变量的隔离性 + + +## lock + +- [example1](src/main/java/com/brianway/learning/java/multithread/lock/example1) + - [Run1_UseConditionWaitNotify.java](src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotify.java):使用 Condition 实现等待通知,Condition 对象的 `await()`方法,线程`WAITING` + - [Run1_UseConditionWaitNotifyError.java](src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyError.java):`IllegalMonitorStateException`,监视器出错 + - [Run1_UseConditionWaitNotifyOk.java](src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyOk.java):正确使用Condition实现等待通知 +- [example2](src/main/java/com/brianway/learning/java/multithread/lock/example2) + - [Run2_MustUseMoreCondition.java](src/main/java/com/brianway/learning/java/multithread/lock/example2/Run2_MustUseMoreCondition.java):使用多个 condition 实现通知部分线程 +- [example3](src/main/java/com/brianway/learning/java/multithread/lock/example3) + - [Run3_ConditionManyToMany.java](src/main/java/com/brianway/learning/java/multithread/lock/example3/Run3_ConditionManyToMany.java):实现生产者/消费者模式,多对多交替打印 +- [example4](src/main/java/com/brianway/learning/java/multithread/lock/example4) + - [Run4_Fair.java](src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_Fair.java):公平锁测试,打印结果呈有序状态 + - [Run4_notFair.java](src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_notFair.java):非公平锁测试,打印结果乱序,先启动的线程不一定先获得锁 +- [example5](src/main/java/com/brianway/learning/java/multithread/lock/example5) + - [Run5_getHoldCount.java](src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getHoldCount.java):测试方法 `int getHoldCount()` + - [Run5_getQueueLength.java](src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getQueueLength.java):测试方法 `int getQueueLength()` + - [Run5_getWaitQueueLength.java](src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getWaitQueueLength.java):测试方法 `int getWaitQueueLength(Condition condition)` +- [example6](src/main/java/com/brianway/learning/java/multithread/lock/example6) + - [Run6_hasQueueThread.java](src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasQueueThread.java):测试方法 `boolean hasQueueThread(Thread thread)` 和 `boolean hasQueueThreads()` + - [Run6_hasWaiters.java](src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasWaiters.java):测试方法 `boolean hasWaiters(Condition)` +- [example7](src/main/java/com/brianway/learning/java/multithread/lock/example7) + - [Run7_isFair.java](src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isFair.java):测试方法 `boolean isFair()` + - [Run7_isHeldByCurrentThread.java](src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isHeldByCurrentThread.java):测试方法 `boolean isHeldByCurrentThread()` + - [Run7_isLocked.java](src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isLocked.java):测试方法 `boolean isLocked()` +- [example8](src/main/java/com/brianway/learning/java/multithread/lock/example8) + - [Run8_lockInterruptibly1.java](src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly1.java):测试方法 `void lockInterruptibly()` + - [Run8_lockInterruptibly2.java](src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly2.java):测试方法 `void lockInterruptibly()` + - [Run8_tryLock.java](src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock.java):测试方法 `boolean tryLock()` + - [Run8_tryLock_param.java](src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock_param.java):测试方法 `boolean tryLock(long timeout,TimeUnit unit)` +- [example9](src/main/java/com/brianway/learning/java/multithread/lock/example9) + - [Run9_awaitUniterruptibly1.java](src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly1.java):测试方法 `awaitUniterruptibly()` + - [Run9_awaitUniterruptibly2.java](src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly2.java):测试方法 `awaitUniterruptibly()` + - [Run9_awaitUntil1.java](src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil1.java):测试方法 `awaitUntil()` + - [Run9_awaitUntil2.java](src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil2.java):测试方法 `awaitUntil()` +- [example10](src/main/java/com/brianway/learning/java/multithread/lock/example10) + - [Run10_condition.java](src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_condition.java):Condition 实现顺序打印 + - [Run10_ReadWriteLockBegin1.java](src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin1.java):类 `ReentrantReadWriteLock` 的使用:读读共享 + - [Run10_ReadWriteLockBegin2.java](src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin2.java):类 `ReentrantReadWriteLock` 的使用:写写互斥 + - [Run10_ReadWriteLockBegin3.java](src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin3.java):类 `ReentrantReadWriteLock` 的使用:读写互斥 + + +## timer + +- [example1](src/main/java/com/brianway/learning/java/multithread/timer/example1):`schedule(TimerTask task, Date time)` 测试 + - [Run1_timer1.java](src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer1.java):在未来执行的效果,Timer 的构造方法会新启一个线程,且非守护线程 + - [Run1_timer2.java](src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer2.java):在未来执行的效果,Timer 的构造方法会新启一个守护线程,迅速结束,task任务未被执行 + - [Run1_timer3.java](src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer3.java):提前运行的效果 + - [Run1_timer4.java](src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer4.java):多个 TimerTask 任务及延时 + - [Run1_timer5.java](src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer5.java):多个TimerTask任务及延时,队列的方式,一个一个被顺序执行,前面一个耗时长则后面的任务被延后 +- [example2](src/main/java/com/brianway/learning/java/multithread/timer/example2):`schedule(TimerTask task, long delay, long period)` 测试 + - [Run2_period1.java](src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period1.java):在未来执行的效果 + - [Run2_period2.java](src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period2.java):提前运行的效果 + - [Run2_period3.java](src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period3.java):任务执行时间被延时 +- [example3](src/main/java/com/brianway/learning/java/multithread/timer/example3) + - [Run3_cancel1.java](src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel1.java):`TimerTask` 类的 `cancel()` 方法,将自身从任务队列移除,其他任务不受影响 + - [Run3_cancel2.java](src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel2.java):`Timer` 类的 `cancel()`方法,全部任务被清除,且进程被销毁 + - [Run3_cancel3.java](src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel3.java):`Timer` 类的 `cancel()`方法,有时不一定会停止计划任务 +- [example4](src/main/java/com/brianway/learning/java/multithread/timer/example4) + - [Run4_schedule1.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule1.java):`schedule(TimerTask task, long delay)` 方法 + - [Run4_schedule2.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule2.java):`schedule(TimerTask task, long delay, long period)` 方法 + - [Run4_schedule3.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule3.java):`schedule(TimerTask task, Date firstTime, long period)` 方法 + - [Run4_schedule4.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule4.java):`schedule(TimerTask task, long delay, long period)` 方法 + - [Run4_schedule5.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule5.java):`schedule(TimerTask task, Date firstTime, long period)` 方法 + - [Run4_schedule6.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule6.java):`schedule(TimerTask task, long delay, long period)` 方法 + - [Run4_schedule_vs_scheduleAtFixedRate_1.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_1.java):schedule 不具有追赶执行性 + - [Run4_schedule_vs_scheduleAtFixedRate_2.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_2.java):scheduleAtFixedRate 具有追赶执行性 + - [Run4_scheduleAtFixedRate1.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate1.java):`scheduleAtFixedRate(TimerTask task, Date firstTime,long period)` 方法 + - [Run4_scheduleAtFixedRate2.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate2.java):`scheduleAtFixedRate(TimerTask task, long delay, long period)` 方法 + - [Run4_scheduleAtFixedRate3.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate3.java):`scheduleAtFixedRate(TimerTask task, Date firstTime, long period)` 方法 + - [Run4_scheduleAtFixedRate4.java](src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate4.java):`scheduleAtFixedRate(TimerTask task, long delay, long period)` 方法 + + +## singleton + + +- [example1](src/main/java/com/brianway/learning/java/multithread/singleton/example1) + - [Run1_singleton0.java](src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton0.java):立即加载/“饿汉模式” + - [Run1_singleton1.java](src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton1.java):延迟加载/“懒汉模式”(会出问题) + - [Run1_singleton2.java](src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton2.java):延迟加载/“懒汉模式”缺点展示 +- [example2](src/main/java/com/brianway/learning/java/multithread/singleton/example2):延迟加载/“懒汉模式”解决方案 + - [Run2_singleton1.java](src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton1.java):声明 `synchronized` 关键字,整个方法上锁 + - [Run2_singleton2.java](src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton2.java):声明 `synchronized` 关键字,同步代码块 + - [Run2_singleton3.java](src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton3.java):声明 `synchronized` 关键字,部分代码上锁 + - [Run2_singleton4.java](src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton4.java):DCL 双检查锁机制 +- [example3](src/main/java/com/brianway/learning/java/multithread/singleton/example3) + - [Run3_singleton1.java](src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton1.java):使用静态内置类实现单例模式 + - [Run3_singleton2.java](src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton2.java):序列化与反序列化的单例模式实现 + - [Run3_singleton3.java](src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton3.java):使用 `static` 代码块实现单例模式 + - [Run3_singleton4.java](src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton4.java):使用 `enum` 枚举数据类型实现单例模式 + - [Run3_singleton5.java](src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton5.java):使用 `enum` 枚举数据类型实现单例模式 + + +## supplement + +- [example1](src/main/java/com/brianway/learning/java/multithread/supplement/example1) + - [Run1_state1.java](src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state1.java):验证 `NEW,RUNNABLE`,`TERMINATED` + - [Run1_state2.java](src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state2.java):验证 `TIMED_WAITING` + - [Run1_state3.java](src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state3.java):验证 `BLOCKED` +- [example2](src/main/java/com/brianway/learning/java/multithread/supplement/example2) + - [Run2_autoAddGroup.java](src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_autoAddGroup.java):线程组自动归属特性 + - [Run2_getGroupParent.java](src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_getGroupParent.java):获取根线程组,JVM 根线程组就是 system + - [Run2_groupAddThread.java](src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThread.java)线程对象关联线程组,一级关联 + - [Run2_groupAddThreadMoreLevel.java](src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThreadMoreLevel.java):线程对象关联线程组,多级关联 + - [Run2_threadRunSyn.java](src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_threadRunSyn.java):使线程具有有序性 +- [example3](src/main/java/com/brianway/learning/java/multithread/supplement/example3) + - [Run3_formatError.java](src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatError.java):`SimpleDateFormat` 类非线程安全 + - [Run3_formatOK1.java](src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK1.java):`SimpleDateFormat` 类非线程安全,解决异常方法一 + - [Run3_formatOK2.java](src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK2.java):`SimpleDateFormat` 类非线程安全,解决异常方法二 +- [example4](src/main/java/com/brianway/learning/java/multithread/supplement/example4) + - [Run4_threadCreateException.java](src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException.java):线程中出现异常 + - [Run4_threadCreateException2.java](src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException2.java):线程中出现异常,捕捉 + - [Run4_threadCreateException3.java](src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException3.java):线程中出现异常,捕捉 +- [example5](src/main/java/com/brianway/learning/java/multithread/supplement/example5) + - [Run5_threadGroup1.java](src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup1.java):线程组内处理异常 + - [Run5_threadGroup2.java](src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup2.java):线程组内处理异常 +- [example6](src/main/java/com/brianway/learning/java/multithread/supplement/example6) + - [Run6_threadExceptionMove1.java](src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove1.java) + - [Run6_threadExceptionMove2.java](src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove2.java) + \ No newline at end of file diff --git a/java-multithread/pom.xml b/java-multithread/pom.xml index ec99a5e..c9f06fe 100644 --- a/java-multithread/pom.xml +++ b/java-multithread/pom.xml @@ -9,7 +9,7 @@ 4.0.0 - java-multihread + java-multithread @@ -18,5 +18,4 @@ - \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java new file mode 100644 index 0000000..5c00c5d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CachedThreadPool.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by brian on 16/11/30. + */ +public class CachedThreadPool { + public static void main(String[] args) { + ExecutorService exec = Executors.newCachedThreadPool(); + for (int i = 0; i < 5; i++) { + exec.execute(new LiftOff()); + } + exec.shutdown(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java new file mode 100644 index 0000000..6bf07d6 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CallableDemo.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.concurrent; + +import java.util.ArrayList; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +/** + * Created by brian on 16/11/30. + */ +public class CallableDemo { + public static void main(String[] args) { + ExecutorService exec = Executors.newCachedThreadPool(); + ArrayList> results = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + results.add(exec.submit(new TaskWithResult(i))); + } + + for (Future fs : results) { + try { + System.out.println(fs.get()); + } catch (InterruptedException e) { + System.out.println(e); + e.printStackTrace(); + } catch (ExecutionException e) { + System.out.println(e); + e.printStackTrace(); + } finally { + exec.shutdown(); + } + } + } +} + +class TaskWithResult implements Callable { + private int id; + + public TaskWithResult(int id) { + this.id = id; + } + + @Override + public String call() throws Exception { + return "result of TaskWithResult " + id; + } +} \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java new file mode 100755 index 0000000..07c4c60 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CaptureUncaughtException.java @@ -0,0 +1,59 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +/** + * TODO 为什么有两个线程? + */ +public class CaptureUncaughtException { + public static void main(String[] args) { + ExecutorService exec = Executors.newCachedThreadPool( + new HandlerThreadFactory()); + exec.execute(new ExceptionThread()); + } +} + +class ExceptionThread implements Runnable { + public void run() { + Thread t = Thread.currentThread(); + System.out.println("run() by " + t); + System.out.println( + "eh = " + t.getUncaughtExceptionHandler()); + throw new RuntimeException(); + } +} + +class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { + public void uncaughtException(Thread t, Throwable e) { + System.out.println("caught " + e + " in " + t); + } +} + +class HandlerThreadFactory implements ThreadFactory { + public Thread newThread(Runnable r) { + System.out.println(this + " creating new Thread"); + Thread t = new Thread(r); + System.out.println("created " + t); + t.setUncaughtExceptionHandler( + new MyUncaughtExceptionHandler()); + System.out.println( + "eh = " + t.getUncaughtExceptionHandler()); + return t; + } +} + + + +/* Output: (90% match) +com.brianway.learning.java.concurrent.HandlerThreadFactory@266474c2 creating new Thread +created Thread[Thread-0,5,main] +eh = com.brianway.learning.java.concurrent.MyUncaughtExceptionHandler@6f94fa3e +run() by Thread[Thread-0,5,main] +eh = com.brianway.learning.java.concurrent.MyUncaughtExceptionHandler@6f94fa3e +com.brianway.learning.java.concurrent.HandlerThreadFactory@266474c2 creating new Thread +created Thread[Thread-1,5,main] +eh = com.brianway.learning.java.concurrent.MyUncaughtExceptionHandler@3ff961b5 +caught java.lang.RuntimeException in Thread[Thread-0,5,main] +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java new file mode 100755 index 0000000..7a5ded2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CloseResource.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.concurrent; + +import java.io.InputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Interrupting a blocked task by closing the underlying resource. + * {RunByHand} + */ +public class CloseResource { + public static void main(String[] args) throws Exception { + ExecutorService exec = Executors.newCachedThreadPool(); + ServerSocket server = new ServerSocket(8080); + InputStream socketInput = + new Socket("localhost", 8080).getInputStream(); + exec.execute(new IOBlocked(socketInput)); + exec.execute(new IOBlocked(System.in)); + TimeUnit.MILLISECONDS.sleep(100); + System.out.println("Shutting down all threads"); + exec.shutdownNow(); + TimeUnit.SECONDS.sleep(1); + System.out.println("Closing " + socketInput.getClass().getName()); + socketInput.close(); // Releases blocked thread + TimeUnit.SECONDS.sleep(1); + System.out.println("Closing " + System.in.getClass().getName()); + System.in.close(); // Releases blocked thread + } +} + +/* Output: (85% match) +Waiting for read(): +Waiting for read(): +Shutting down all threads +Closing java.net.SocketInputStream +Interrupted from blocked I/O +Exiting IOBlocked.run() +Closing java.io.BufferedInputStream +Exiting IOBlocked.run() +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java new file mode 100755 index 0000000..5c3fcf9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/CountDownLatchDemo.java @@ -0,0 +1,81 @@ +package com.brianway.learning.java.concurrent; + +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class CountDownLatchDemo { + static final int SIZE = 10; + + public static void main(String[] args) throws Exception { + ExecutorService exec = Executors.newCachedThreadPool(); + // All must share a single CountDownLatch object: + CountDownLatch latch = new CountDownLatch(SIZE); + for (int i = 0; i < 10; i++) + exec.execute(new WaitingTask(latch)); + for (int i = 0; i < SIZE; i++) + exec.execute(new TaskPortion(latch)); + System.out.println("Launched all tasks"); + exec.shutdown(); // Quit when all tasks complete + } +} + +// Performs some portion of a task: +class TaskPortion implements Runnable { + private static int counter = 0; + private final int id = counter++; + private static Random rand = new Random(47); + private final CountDownLatch latch; + + TaskPortion(CountDownLatch latch) { + this.latch = latch; + } + + public void run() { + try { + doWork(); + latch.countDown(); + latch.await(); + System.out.println(this + " TaskPortion after await"); + } catch (InterruptedException ex) { + // Acceptable way to exit + } + } + + public void doWork() throws InterruptedException { + TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000)); + System.out.println(this + "completed"); + } + + public String toString() { + return String.format("%1$-3d ", id); + } +} + +// Waits on the CountDownLatch: +class WaitingTask implements Runnable { + private static int counter = 0; + private final int id = counter++; + private final CountDownLatch latch; + + WaitingTask(CountDownLatch latch) { + this.latch = latch; + } + + public void run() { + try { + latch.await(); + System.out.println("Latch barrier passed for " + this); + } catch (InterruptedException ex) { + System.out.println(this + " interrupted"); + } + } + + public String toString() { + return String.format("WaitingTask %1$-3d ", id); + } +} + +/* (Execute to see output) *///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java new file mode 100755 index 0000000..46004ff --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonFromFactory.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Using a Thread Factory to create daemons. + */ +public class DaemonFromFactory implements Runnable { + public void run() { + try { + while (true) { + TimeUnit.MILLISECONDS.sleep(100); + System.out.println(Thread.currentThread() + " " + this); + } + } catch (InterruptedException e) { + System.out.println("Interrupted"); + } + } + + public static void main(String[] args) throws Exception { + ExecutorService exec = Executors.newCachedThreadPool( + new DaemonThreadFactory()); + for (int i = 0; i < 10; i++) + exec.execute(new DaemonFromFactory()); + System.out.println("All daemons started"); + TimeUnit.MILLISECONDS.sleep(500); // Run for a while + } +} /* (Execute to see output) *///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java new file mode 100644 index 0000000..506f98b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonThreadFactory.java @@ -0,0 +1,15 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ThreadFactory; + +/** + * Created by brian on 16/12/1. + */ +public class DaemonThreadFactory implements ThreadFactory { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java new file mode 100755 index 0000000..86de25b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/DaemonsDontRunFinally.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * Daemon threads don't run the finally clause + * + * output:"Starting ADaemon" or nothing + */ + +public class DaemonsDontRunFinally { + public static void main(String[] args) throws Exception { + Thread t = new Thread(new ADaemon()); + t.setDaemon(true); + t.start(); + } +} + +class ADaemon implements Runnable { + public void run() { + try { + System.out.println("Starting ADaemon"); + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + System.out.println("Exiting via InterruptedException"); + } finally { + System.out.println("This should always run?"); + } + } +} +/* Output: +Starting ADaemon + +or + +output nothing +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java new file mode 100644 index 0000000..fe9f063 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/FixedThreadPool.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by brian on 16/11/30. + */ +public class FixedThreadPool { + public static void main(String[] args) { + ExecutorService exec = Executors.newFixedThreadPool(5); + for (int i = 0; i < 5; i++) { + exec.execute(new LiftOff()); + } + exec.shutdown(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java new file mode 100755 index 0000000..1118727 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Interrupting.java @@ -0,0 +1,106 @@ +package com.brianway.learning.java.concurrent; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + * Interrupting a blocked thread. + * + * + */ +public class Interrupting { + private static ExecutorService exec = + Executors.newCachedThreadPool(); + + static void test(Runnable r) throws InterruptedException { + Future f = exec.submit(r); + TimeUnit.MILLISECONDS.sleep(100); + System.out.println("Interrupting " + r.getClass().getSimpleName()); + f.cancel(true); // Interrupts if running + System.out.println("Interrupt sent to " + r.getClass().getSimpleName()); + } + + public static void main(String[] args) throws Exception { + test(new SleepBlocked()); + test(new IOBlocked(System.in)); + test(new SynchronizedBlocked()); + TimeUnit.SECONDS.sleep(3); + System.out.println("Aborting with System.exit(0)"); + System.exit(0); // ... since last 2 interrupts failed + } +} + +/** + * 可中断的阻塞示例 + */ +class SleepBlocked implements Runnable { + public void run() { + try { + TimeUnit.SECONDS.sleep(100); + } catch (InterruptedException e) { + System.out.println("InterruptedException"); + } + System.out.println("Exiting SleepBlocked.run()"); + } +} + +class IOBlocked implements Runnable { + private InputStream in; + + public IOBlocked(InputStream is) { + in = is; + } + + public void run() { + try { + System.out.println("Waiting for read():"); + in.read(); + } catch (IOException e) { + if (Thread.currentThread().isInterrupted()) { + System.out.println("Interrupted from blocked I/O"); + } else { + throw new RuntimeException(e); + } + } + System.out.println("Exiting IOBlocked.run()"); + } +} + +class SynchronizedBlocked implements Runnable { + public synchronized void f() { + while (true) // Never releases lock + Thread.yield(); + } + + public SynchronizedBlocked() { + new Thread() { + public void run() { + f(); // Lock acquired by this thread + } + }.start(); + } + + public void run() { + System.out.println("Trying to call f()"); + f(); + System.out.println("Exiting SynchronizedBlocked.run()"); + } +} + +/* Output: (95% match) +Interrupting SleepBlocked +Interrupt sent to SleepBlocked +InterruptedException +Exiting SleepBlocked.run() +Waiting for read(): +Interrupting IOBlocked +Interrupt sent to IOBlocked +Trying to call f() +Interrupting SynchronizedBlocked +Interrupt sent to SynchronizedBlocked +Aborting with System.exit(0) +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java new file mode 100755 index 0000000..208db8d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/InterruptingIdiom.java @@ -0,0 +1,83 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * General idiom for interrupting a task. + * {Args: 1100} + */ +public class InterruptingIdiom { + public static void main(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("usage: java InterruptingIdiom delay-in-mS"); + System.exit(1); + } + Thread t = new Thread(new Blocked3()); + t.start(); + TimeUnit.MILLISECONDS.sleep(new Integer(args[0])); + t.interrupt(); + } +} + +class NeedsCleanup { + private final int id; + + public NeedsCleanup(int ident) { + id = ident; + System.out.println("NeedsCleanup " + id); + } + + public void cleanup() { + System.out.println("Cleaning up " + id); + } +} + +class Blocked3 implements Runnable { + private volatile double d = 0.0; + + public void run() { + try { + while (!Thread.interrupted()) { + // point1 + NeedsCleanup n1 = new NeedsCleanup(1); + // Start try-finally immediately after definition + // of n1, to guarantee proper cleanup of n1: + try { + System.out.println("Sleeping"); + TimeUnit.SECONDS.sleep(1); + // point2 + NeedsCleanup n2 = new NeedsCleanup(2); + // Guarantee proper cleanup of n2: + try { + System.out.println("Calculating"); + // A time-consuming, non-blocking operation: + for (int i = 1; i < 2500000; i++) + d = d + (Math.PI + Math.E) / d; + System.out.println("Finished time-consuming operation"); + } finally { + n2.cleanup(); + } + } finally { + n1.cleanup(); + } + } + System.out.println("Exiting via while() test"); + } catch (InterruptedException e) { + System.out.println("Exiting via InterruptedException"); + } + } +} + +/* Output: (Sample) +NeedsCleanup 1 +Sleeping +NeedsCleanup 2 +Calculating +Finished time-consuming operation +Cleaning up 2 +Cleaning up 1 +NeedsCleanup 1 +Sleeping +Cleaning up 1 +Exiting via InterruptedException +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java new file mode 100755 index 0000000..a3e5532 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/Joining.java @@ -0,0 +1,64 @@ +package com.brianway.learning.java.concurrent; + +/** + * Understanding join(). + * + * 异常捕获时将清理标志位 + */ +class Sleeper extends Thread { + private int duration; + + public Sleeper(String name, int sleepTime) { + super(name); + duration = sleepTime; + start(); + } + + public void run() { + try { + sleep(duration); + } catch (InterruptedException e) { + System.out.println(getName() + " was interrupted. " + + "isInterrupted(): " + isInterrupted()); + return; + } + System.out.println(getName() + " has awakened"); + } +} + +class Joiner extends Thread { + private Sleeper sleeper; + + public Joiner(String name, Sleeper sleeper) { + super(name); + this.sleeper = sleeper; + start(); + } + + public void run() { + try { + sleeper.join(); + } catch (InterruptedException e) { + System.out.println("Interrupted"); + } + System.out.println(getName() + " join completed"); + } +} + +public class Joining { + public static void main(String[] args) { + Sleeper + sleepy = new Sleeper("Sleepy", 1500), + grumpy = new Sleeper("Grumpy", 1500); + Joiner + dopey = new Joiner("Dopey", sleepy), + doc = new Joiner("Doc", grumpy); + grumpy.interrupt(); + } +} +/* Output: +Grumpy was interrupted. isInterrupted(): false +Doc join completed +Sleepy has awakened +Dopey join completed +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java new file mode 100644 index 0000000..c42f9cf --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/LiftOff.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.concurrent; + +/** + * Created by brian on 16/11/30. + */ +public class LiftOff implements Runnable { + protected int countDown = 10; + private static int taskCount = 0; + private final int id = taskCount++; + + public LiftOff() { + } + + public LiftOff(int countDown) { + this.countDown = countDown; + } + + public String status() { + return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff!") + "), "; + } + + @Override + public void run() { + while (countDown-- > 0) { + System.out.print(status()); + Thread.yield(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java new file mode 100644 index 0000000..0aec425 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/MoreBasicThreads.java @@ -0,0 +1,13 @@ +package com.brianway.learning.java.concurrent; + +/** + * Created by brian on 16/11/30. + */ +public class MoreBasicThreads { + public static void main(String[] args) { + for (int i = 0; i < 5; i++) { + new Thread(new LiftOff()).start(); + } + System.out.println("Waiting for LiftOff"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java new file mode 100755 index 0000000..11a0eca --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/OrnamentalGarden.java @@ -0,0 +1,101 @@ +package com.brianway.learning.java.concurrent; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +class Count { + private int count = 0; + private Random rand = new Random(47); + + // Remove the synchronized keyword to see counting fail: + public synchronized int increment() { + int temp = count; + if (rand.nextBoolean()) // Yield half the time + { + Thread.yield(); + } + return (count = ++temp); + } + + public synchronized int value() { + return count; + } +} + +class Entrance implements Runnable { + private static Count count = new Count(); + private static List entrances = + new ArrayList(); + private int number = 0; + // Doesn't need synchronization to read: + private final int id; + private static volatile boolean canceled = false; + + // Atomic operation on a volatile field: + public static void cancel() { + canceled = true; + } + + public Entrance(int id) { + this.id = id; + // Keep this task in a list. Also prevents + // garbage collection of dead tasks: + entrances.add(this); + } + + public void run() { + while (!canceled) { + synchronized (this) { + ++number; + } + System.out.println(this + " Total: " + count.increment()); + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + System.out.println("sleep interrupted"); + } + } + System.out.println("Stopping " + this); + } + + public synchronized int getValue() { + return number; + } + + public String toString() { + return "Entrance " + id + ": " + getValue(); + } + + public static int getTotalCount() { + return count.value(); + } + + public static int sumEntrances() { + int sum = 0; + for (Entrance entrance : entrances) + sum += entrance.getValue(); + return sum; + } +} + +public class OrnamentalGarden { + public static void main(String[] args) throws Exception { + ExecutorService exec = Executors.newCachedThreadPool(); + for (int i = 0; i < 5; i++) + exec.execute(new Entrance(i)); + // Run for a while, then stop and collect the data: + TimeUnit.SECONDS.sleep(3); + Entrance.cancel(); + exec.shutdown(); + if (!exec.awaitTermination(250, TimeUnit.MILLISECONDS)) { + System.out.println("Some tasks were not terminated!"); + } + System.out.println("Total: " + Entrance.getTotalCount()); + System.out.println("Sum of Entrances: " + Entrance.sumEntrances()); + } +} + diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java new file mode 100755 index 0000000..b21de44 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/PipedIO.java @@ -0,0 +1,71 @@ +package com.brianway.learning.java.concurrent; + +import java.io.IOException; +import java.io.PipedReader; +import java.io.PipedWriter; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Using pipes for inter-task I/O + */ +public class PipedIO { + public static void main(String[] args) throws Exception { + Sender sender = new Sender(); + Receiver receiver = new Receiver(sender); + ExecutorService exec = Executors.newCachedThreadPool(); + exec.execute(sender); + exec.execute(receiver); + TimeUnit.SECONDS.sleep(4); + exec.shutdownNow(); + } +} + +class Sender implements Runnable { + private Random rand = new Random(47); + private PipedWriter out = new PipedWriter(); + + public PipedWriter getPipedWriter() { + return out; + } + + public void run() { + try { + while (true) + for (char c = 'A'; c <= 'z'; c++) { + out.write(c); + TimeUnit.MILLISECONDS.sleep(rand.nextInt(500)); + } + } catch (IOException e) { + System.out.println(e + " Sender write exception"); + } catch (InterruptedException e) { + System.out.println(e + " Sender sleep interrupted"); + } + } +} + +class Receiver implements Runnable { + private PipedReader in; + + public Receiver(Sender sender) throws IOException { + in = new PipedReader(sender.getPipedWriter()); + } + + public void run() { + try { + while (true) { + // Blocks until characters are there: + System.out.print("Read: " + (char) in.read() + ", "); + } + } catch (IOException e) { + System.out.println(e + " Receiver read exception"); + } + } +} + +/* Output: (65% match) +Read: A, Read: B, Read: C, Read: D, Read: E, Read: F, Read: G, Read: H, Read: I, Read: J, Read: K, Read: L, Read: M, java.lang.InterruptedException: sleep interrupted Sender sleep interrupted +java.io.InterruptedIOException Receiver read exception +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java new file mode 100755 index 0000000..6a6d477 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SimpleDaemons.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.TimeUnit; + +/** + * Daemon threads don't prevent the program from ending. + */ +public class SimpleDaemons implements Runnable { + public void run() { + try { + while (true) { + TimeUnit.MILLISECONDS.sleep(100); + System.out.println(Thread.currentThread() + " " + this); + } + } catch (InterruptedException e) { + System.out.println("sleep() interrupted"); + } + } + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 10; i++) { + Thread daemon = new Thread(new SimpleDaemons()); + daemon.setDaemon(true); // Must call before start() + daemon.start(); + } + System.out.println("All daemons started"); + TimeUnit.MILLISECONDS.sleep(175); + } +} + +/* Output: (Sample) +All daemons started +Thread[Thread-8,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@1ec8f532 +Thread[Thread-4,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@17d10736 +Thread[Thread-1,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@2eec0173 +Thread[Thread-0,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@78f0e569 +Thread[Thread-5,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@572f3b73 +Thread[Thread-6,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@6c8d15b7 +Thread[Thread-2,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@31229a57 +Thread[Thread-3,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@4059e324 +Thread[Thread-9,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@32e39829 +Thread[Thread-7,5,main] com.brianway.learning.java.concurrent.SimpleDaemons@45401023 + +... +*///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java new file mode 100644 index 0000000..dc70e5c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SingleThreadExecutor.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by brian on 16/11/30. + */ +public class SingleThreadExecutor { + public static void main(String[] args) { + ExecutorService exec = Executors.newSingleThreadExecutor(); + for (int i = 0; i < 5; i++) { + exec.execute(new LiftOff()); + } + exec.shutdown(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java new file mode 100644 index 0000000..b53f1f4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/SleepingTask.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.concurrent; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Created by brian on 16/11/30. + */ +public class SleepingTask extends LiftOff { + @Override + public void run() { + try { + while (countDown-- > 0) { + System.out.print(status()); + TimeUnit.MILLISECONDS.sleep(100); + } + } catch (InterruptedException e) { + System.err.println("Interrupted"); + } + } + + public static void main(String[] args) { + ExecutorService exec = Executors.newCachedThreadPool(); + for (int i = 0; i < 5; i++) { + exec.execute(new SleepingTask()); + } + exec.shutdown(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java new file mode 100755 index 0000000..9591ad7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/TestBlockingQueues.java @@ -0,0 +1,77 @@ +package com.brianway.learning.java.concurrent; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.SynchronousQueue; + +public class TestBlockingQueues { + static void getkey() { + try { + // Compensate for Windows/Linux difference in the + // length of the result produced by the Enter key: + new BufferedReader( + new InputStreamReader(System.in)).readLine(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + static void getkey(String message) { + System.out.println(message); + getkey(); + } + + static void test(String msg, BlockingQueue queue) { + System.out.println(msg); + LiftOffRunner runner = new LiftOffRunner(queue); + Thread t = new Thread(runner); + t.start(); + for (int i = 0; i < 5; i++) { + runner.add(new LiftOff(5)); + } + getkey("Press 'Enter' (" + msg + ")"); + t.interrupt(); + System.out.println("Finished " + msg + " test"); + } + + public static void main(String[] args) { + test("LinkedBlockingQueue", // Unlimited size + new LinkedBlockingQueue()); + test("ArrayBlockingQueue", // Fixed size + new ArrayBlockingQueue(3)); + test("SynchronousQueue", // Size of 1 + new SynchronousQueue()); + } +} + +class LiftOffRunner implements Runnable { + private BlockingQueue rockets; + + public LiftOffRunner(BlockingQueue queue) { + rockets = queue; + } + + public void add(LiftOff lo) { + try { + rockets.put(lo); + } catch (InterruptedException e) { + System.out.println("Interrupted during put()"); + } + } + + public void run() { + try { + while (!Thread.interrupted()) { + LiftOff rocket = rockets.take(); + rocket.run(); // Use this thread + } + } catch (InterruptedException e) { + System.out.println("Waking from take()"); + } + System.out.println("Exiting LiftOffRunner"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java new file mode 100755 index 0000000..021668a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/concurrent/ToastOMatic.java @@ -0,0 +1,174 @@ +package com.brianway.learning.java.concurrent; + +/** + * A toaster that uses queues. + */ + +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +public class ToastOMatic { + public static void main(String[] args) throws Exception { + ToastQueue dryQueue = new ToastQueue(), + butteredQueue = new ToastQueue(), + finishedQueue = new ToastQueue(); + ExecutorService exec = Executors.newCachedThreadPool(); + exec.execute(new Toaster(dryQueue)); + exec.execute(new Butterer(dryQueue, butteredQueue)); + exec.execute(new Jammer(butteredQueue, finishedQueue)); + exec.execute(new Eater(finishedQueue)); + TimeUnit.SECONDS.sleep(5); + exec.shutdownNow(); + } +} + +class Toast { + public enum Status { + DRY, + BUTTERED, + JAMMED + } + + private Status status = Status.DRY; + private final int id; + + public Toast(int idn) { + id = idn; + } + + public void butter() { + status = Status.BUTTERED; + } + + public void jam() { + status = Status.JAMMED; + } + + public Status getStatus() { + return status; + } + + public int getId() { + return id; + } + + public String toString() { + return "Toast " + id + ": " + status; + } +} + +class ToastQueue extends LinkedBlockingQueue { +} + +class Toaster implements Runnable { + private ToastQueue toastQueue; + private int count = 0; + private Random rand = new Random(47); + + public Toaster(ToastQueue tq) { + toastQueue = tq; + } + + public void run() { + try { + while (!Thread.interrupted()) { + TimeUnit.MILLISECONDS.sleep( + 100 + rand.nextInt(500)); + // Make toast + Toast t = new Toast(count++); + System.out.println(t); + // Insert into queue + toastQueue.put(t); + } + } catch (InterruptedException e) { + System.out.println("Toaster interrupted"); + } + System.out.println("Toaster off"); + } +} + +// Apply butter to toast: +class Butterer implements Runnable { + private ToastQueue dryQueue, butteredQueue; + + public Butterer(ToastQueue dry, ToastQueue buttered) { + dryQueue = dry; + butteredQueue = buttered; + } + + public void run() { + try { + while (!Thread.interrupted()) { + // Blocks until next piece of toast is available: + Toast t = dryQueue.take(); + t.butter(); + System.out.println(t); + butteredQueue.put(t); + } + } catch (InterruptedException e) { + System.out.println("Butterer interrupted"); + } + System.out.println("Butterer off"); + } +} + +// Apply jam to buttered toast: +class Jammer implements Runnable { + private ToastQueue butteredQueue, finishedQueue; + + public Jammer(ToastQueue buttered, ToastQueue finished) { + butteredQueue = buttered; + finishedQueue = finished; + } + + public void run() { + try { + while (!Thread.interrupted()) { + // Blocks until next piece of toast is available: + Toast t = butteredQueue.take(); + t.jam(); + System.out.println(t); + finishedQueue.put(t); + } + } catch (InterruptedException e) { + System.out.println("Jammer interrupted"); + } + System.out.println("Jammer off"); + } +} + +// Consume the toast: +class Eater implements Runnable { + private ToastQueue finishedQueue; + private int counter = 0; + + public Eater(ToastQueue finished) { + finishedQueue = finished; + } + + public void run() { + try { + while (!Thread.interrupted()) { + // Blocks until next piece of toast is available: + Toast t = finishedQueue.take(); + // Verify that the toast is coming in order, + // and that all pieces are getting jammed: + if (t.getId() != counter++ || + t.getStatus() != Toast.Status.JAMMED) { + System.out.println(">>>> Error: " + t); + System.exit(1); + } else { + System.out.println("Chomp! " + t); + } + } + } catch (InterruptedException e) { + System.out.println("Eater interrupted"); + } + System.out.println("Eater off"); + } +} + +/* (Execute to see output) *///:~ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/MyList.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/MyList.java index f78403d..0411280 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/MyList.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/MyList.java @@ -1,6 +1,5 @@ package com.brianway.learning.java.multithread.communication.example1; - import java.util.ArrayList; import java.util.List; @@ -10,10 +9,11 @@ public class MyList { private List list = new ArrayList(); - public void add(){ + public void add() { list.add("brian"); } - public int size(){ + + public int size() { return list.size(); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/Run1_TwoThreadTransData.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/Run1_TwoThreadTransData.java index cdc5b50..6874adb 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/Run1_TwoThreadTransData.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/Run1_TwoThreadTransData.java @@ -13,7 +13,7 @@ public class Run1_TwoThreadTransData { public static void main(String[] args) { MyList service = new MyList(); - ThreadA a =new ThreadA(service); + ThreadA a = new ThreadA(service); a.setName("A"); a.start(); ThreadB b = new ThreadB(service); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadA.java index 225099b..9b8819b 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadA.java @@ -13,9 +13,9 @@ public ThreadA(MyList list) { @Override public void run() { - for(int i = 0;i<10;i++){ + for (int i = 0; i < 10; i++) { list.add(); - System.out.println("添加了"+(i+1)+"元素"); + System.out.println("添加了" + (i + 1) + "元素"); try { Thread.sleep(1000); } catch (InterruptedException e) { diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadB.java index 88b5a10..541dea8 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadB.java @@ -14,10 +14,10 @@ public ThreadB(MyList list) { @Override public void run() { try { - while (true){ + while (true) { //System.out.println("in b while: "+list.size()); //synchronized ("any"){} - if(list.size() == 5){ + if (list.size() == 5) { System.out.println("达到size了,线程b要退出了"); throw new InterruptedException(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/C_Thread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/C_Thread.java index c7f4fda..417d213 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/C_Thread.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/C_Thread.java @@ -3,7 +3,7 @@ /** * Created by Brian on 2016/4/14. */ -public class C_Thread extends Thread{ +public class C_Thread extends Thread { private Consumer c; public C_Thread(Consumer c) { @@ -13,7 +13,7 @@ public C_Thread(Consumer c) { @Override public void run() { - while (true){ + while (true) { c.popService(); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Consumer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Consumer.java index dda8267..c5773d0 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Consumer.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Consumer.java @@ -11,8 +11,8 @@ public Consumer(MyStack myStack) { this.myStack = myStack; } - public void popService(){ - System.out.println("pop = "+ myStack.pop()+" Consumer的popService方法中打印pop返回值"); + public void popService() { + System.out.println("pop = " + myStack.pop() + " Consumer的popService方法中打印pop返回值"); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/MyStack.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/MyStack.java index d11d328..c70bb38 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/MyStack.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/MyStack.java @@ -9,31 +9,31 @@ public class MyStack { private List list = new ArrayList(); - synchronized public void push(){ + synchronized public void push() { try { - while(list.size()== 1){ - System.out.println("push操作中的: "+ Thread.currentThread().getName()+ " 线程呈wait状态"); + while (list.size() == 1) { + System.out.println("push操作中的: " + Thread.currentThread().getName() + " 线程呈wait状态"); this.wait(); } list.add(Math.random()); this.notify(); - System.out.println("push = " + list.size() ); + System.out.println("push = " + list.size()); } catch (InterruptedException e) { e.printStackTrace(); } } - synchronized public String pop(){ + synchronized public String pop() { String returnValue = ""; try { - while(list.size() == 0){ - System.out.println("pop操作中的: "+ Thread.currentThread().getName()+ " 线程呈wait状态"); + while (list.size() == 0) { + System.out.println("pop操作中的: " + Thread.currentThread().getName() + " 线程呈wait状态"); this.wait(); } - returnValue =list.get(0)+ " "+Thread.currentThread().getName() ; + returnValue = list.get(0) + " " + Thread.currentThread().getName(); list.remove(0); this.notify(); - System.out.println("pop = "+ list.size()+" Mystack的pop方法中 线程"+Thread.currentThread().getName()); + System.out.println("pop = " + list.size() + " Mystack的pop方法中 线程" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/P_Thread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/P_Thread.java index 8b8aedd..ef0c576 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/P_Thread.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/P_Thread.java @@ -3,7 +3,7 @@ /** * Created by Brian on 2016/4/14. */ -public class P_Thread extends Thread{ +public class P_Thread extends Thread { private Producer p; public P_Thread(Producer p) { @@ -13,7 +13,7 @@ public P_Thread(Producer p) { @Override public void run() { - while (true){ + while (true) { p.pushService(); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Producer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Producer.java index 48dd927..14e6eb2 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Producer.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Producer.java @@ -1,17 +1,17 @@ package com.brianway.learning.java.multithread.communication.example10; - /** * Created by Brian on 2016/4/14. */ public class Producer { private MyStack myStack; - public Producer(MyStack myStack){ + + public Producer(MyStack myStack) { super(); this.myStack = myStack; } - public void pushService(){ + public void pushService() { myStack.push(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Run10_oneP_manyC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Run10_oneP_manyC.java index 89a7586..286da3f 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Run10_oneP_manyC.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Run10_oneP_manyC.java @@ -10,7 +10,6 @@ * * while判断解决条件发生改变时没有得到及时的响应,多个呈wait状态的线程被唤醒的问题 * 但会出现新的问题:假死 - * */ public class Run10_oneP_manyC { public static void main(String[] args) { @@ -20,20 +19,19 @@ public static void main(String[] args) { P_Thread p_thread = new P_Thread(p); p_thread.start(); - int cNum = 5; Consumer[] consumers = new Consumer[cNum]; C_Thread[] c_threads = new C_Thread[cNum]; - for(int i=0;ilock2代码顺序执行"); } } } - if(username.equals("b")){ - synchronized (lock2){ + if (username.equals("b")) { + synchronized (lock2) { try { System.out.println("username = " + username); Thread.sleep(2000); @@ -37,7 +37,7 @@ public void run() { e.printStackTrace(); } - synchronized (lock1){ + synchronized (lock1) { System.out.println("按lock2->lock1代码顺序执行"); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/Run12_deadLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/Run12_deadLock.java index f4c7eac..7b982cd 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/Run12_deadLock.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/Run12_deadLock.java @@ -14,11 +14,11 @@ public static void main(String[] args) { try { DealThread t1 = new DealThread(); t1.setFlag("a"); - Thread thread1 =new Thread(t1); + Thread thread1 = new Thread(t1); thread1.start(); Thread.sleep(100); t1.setFlag("b"); - Thread thread2 =new Thread(t1); + Thread thread2 = new Thread(t1); thread2.start(); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass.java index 05723f3..bfa8da8 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass.java @@ -4,11 +4,11 @@ * Created by Brian on 2016/4/13. */ public class OutClass { - static class Inner{ + static class Inner { public void method1() { - synchronized ("其他的锁"){ - for (int i=1;i<=10;i++){ - System.out.println(Thread.currentThread().getName()+" i="+ i); + synchronized ("其他的锁") { + for (int i = 1; i <= 10; i++) { + System.out.println(Thread.currentThread().getName() + " i=" + i); try { Thread.sleep(100); } catch (InterruptedException e) { @@ -18,9 +18,9 @@ public void method1() { } } - public synchronized void method2(){ - for (int i=11;i<=20;i++){ - System.out.println(Thread.currentThread().getName()+" i="+ i); + public synchronized void method2() { + for (int i = 11; i <= 20; i++) { + System.out.println(Thread.currentThread().getName() + " i=" + i); try { Thread.sleep(100); } catch (InterruptedException e) { diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass2.java index d5fab6b..27bb7da 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass2.java @@ -4,8 +4,8 @@ * Created by Brian on 2016/4/13. */ public class OutClass2 { - static class InnerClass1{ - public void method1(InnerClass2 class2){ + static class InnerClass1 { + public void method1(InnerClass2 class2) { String threadName = Thread.currentThread().getName(); synchronized (class2) { System.out.println(threadName + " 进入InnerClass1类中的method1方法"); @@ -21,7 +21,7 @@ public void method1(InnerClass2 class2){ } } - public synchronized void method2(){ + public synchronized void method2() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " 进入InnerClass1类中的method2方法"); @@ -39,8 +39,8 @@ public synchronized void method2(){ } - static class InnerClass2{ - public synchronized void method1(){ + static class InnerClass2 { + public synchronized void method1() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " 进入InnerClass2类中的method2方法"); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java index 54a7583..21bbe0c 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java @@ -2,27 +2,26 @@ /** * Created by Brian on 2016/4/13. - */ - - -/** + * * P112 * 内置类和同步测试1 */ + import com.brianway.learning.java.multithread.synchronize.example13.OutClass.Inner; + public class Run13_inner01 { public static void main(String[] args) { final Inner inner = new Inner(); Thread t1 = new Thread(new Runnable() { - public void run() { - inner.method1(); - } - },"A"); + public void run() { + inner.method1(); + } + }, "A"); Thread t2 = new Thread(new Runnable() { public void run() { inner.method2(); } - },"B"); + }, "B"); t1.start(); t2.start(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java index 86a7189..b93a5b7 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java @@ -2,6 +2,18 @@ /** * Created by Brian on 2016/4/13. + * + * P112 + * 内置类与同步测试2 + * + * T1和T3竞争in2的锁。只有T1结束,T3才能开始;或者T3结束,T1才能开始 + * T2与另外两个没关系,因为其锁对象是in2 + * + * P112 + * 内置类与同步测试2 + * + * T1和T3竞争in2的锁。只有T1结束,T3才能开始;或者T3结束,T1才能开始 + * T2与另外两个没关系,因为其锁对象是in2 */ /** @@ -15,7 +27,6 @@ import com.brianway.learning.java.multithread.synchronize.example13.OutClass2.InnerClass1; import com.brianway.learning.java.multithread.synchronize.example13.OutClass2.InnerClass2; - public class Run13_inner02 { public static void main(String[] args) { final InnerClass1 in1 = new InnerClass1(); @@ -24,19 +35,19 @@ public static void main(String[] args) { public void run() { in1.method1(in2); } - },"T1"); + }, "T1"); - Thread t2 = new Thread(new Runnable() { + Thread t2 = new Thread(new Runnable() { public void run() { in1.method2(); } - },"T2"); + }, "T2"); - Thread t3 = new Thread(new Runnable() { + Thread t3 = new Thread(new Runnable() { public void run() { in2.method1(); } - },"T3"); + }, "T3"); t1.start(); t2.start(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Run14_setNewStringTwoLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Run14_setNewStringTwoLock.java index 3a00818..83cd9a7 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Run14_setNewStringTwoLock.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Run14_setNewStringTwoLock.java @@ -9,16 +9,16 @@ * 锁对象改变 */ public class Run14_setNewStringTwoLock { - public static void main(String[] args) throws InterruptedException{ + public static void main(String[] args) throws InterruptedException { final Service service = new Service(); - Thread a = new Thread(){ + Thread a = new Thread() { @Override public void run() { service.testMethod(); } }; a.setName("A"); - Thread b = new Thread(){ + Thread b = new Thread() { @Override public void run() { service.testMethod(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Service.java index 092b08b..bfeda5f 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Service.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Service.java @@ -8,11 +8,11 @@ public class Service { public void testMethod() { try { - synchronized (lock){ - System.out.println(Thread.currentThread().getName() + " begin "+ System.currentTimeMillis()); + synchronized (lock) { + System.out.println(Thread.currentThread().getName() + " begin " + System.currentTimeMillis()); lock = "456"; Thread.sleep(2000); - System.out.println(Thread.currentThread().getName() + " end "+ System.currentTimeMillis()); + System.out.println(Thread.currentThread().getName() + " end " + System.currentTimeMillis()); } } catch (InterruptedException e) { diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_synchronized.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_synchronized.java index 1e5e686..c9ccc3c 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_synchronized.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_synchronized.java @@ -6,7 +6,7 @@ /** * P130 - * sychronized代码块有volatile同步的功能 + * synchronized代码块有volatile同步的功能 */ public class Run15_synchronized { public static void main(String[] args) { diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread.java index 68dc879..48df5b5 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread.java @@ -3,11 +3,11 @@ /** * Created by Brian on 2016/4/13. */ -public class RunThread extends Thread{ - private boolean isRunning = true; +public class RunThread extends Thread { + private boolean isRunning = true; //volatile private boolean isRunning = true; - public boolean isRunning(){ + public boolean isRunning() { return isRunning; } @@ -18,7 +18,7 @@ public void setRunning(boolean running) { @Override public void run() { System.out.println("进入run了"); - while(isRunning == true ){ + while (isRunning == true) { } System.out.println("线程被停止了"); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread2.java index dd016ba..ccf5b68 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread2.java @@ -3,10 +3,10 @@ /** * Created by Brian on 2016/4/13. */ -public class RunThread2 extends Thread{ - private boolean isRunning = true; +public class RunThread2 extends Thread { + private boolean isRunning = true; - public boolean isRunning(){ + public boolean isRunning() { return isRunning; } @@ -17,8 +17,9 @@ public void setRunning(boolean running) { @Override public void run() { System.out.println("进入run了"); - while(isRunning == true ){ - synchronized ("any thing"){} + while (isRunning == true) { + synchronized ("any thing") { + } } System.out.println("线程被停止了"); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/MyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/MyThread.java index 1e42949..4adef41 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/MyThread.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/MyThread.java @@ -5,12 +5,13 @@ */ public class MyThread extends Thread { volatile public static int count; + //synchronized - private static void addCount(){ - for(int i=0;i<100;i++) { + private static void addCount() { + for (int i = 0; i < 100; i++) { count++; } - System.out.println("count="+count); + System.out.println("count=" + count); } @Override diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/Run16_volatile.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/Run16_volatile.java index 4e80260..055d320 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/Run16_volatile.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/Run16_volatile.java @@ -11,10 +11,10 @@ public class Run16_volatile { public static void main(String[] args) { MyThread[] myThreads = new MyThread[100]; - for(int i=0;i<100;i++){ - myThreads[i]= new MyThread(); + for (int i = 0; i < 100; i++) { + myThreads[i] = new MyThread(); } - for(int i=0;i<100;i++){ + for (int i = 0; i < 100; i++) { myThreads[i].start(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/HasSelfPrivateNum.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/HasSelfPrivateNum.java index ee7ce02..c50898a 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/HasSelfPrivateNum.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/HasSelfPrivateNum.java @@ -5,19 +5,20 @@ */ public class HasSelfPrivateNum { private int num = 0; + synchronized - public void addI(String username){ + public void addI(String username) { try { - if(username.equals("a")) { + if (username.equals("a")) { num = 100; System.out.println("a set over"); Thread.sleep(2000); - }else{ + } else { num = 200; System.out.println("b set over"); } - System.out.println(username + " num= "+num); + System.out.println(username + " num= " + num); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_private01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_private01.java index acbd1a0..4b56d00 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_private01.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_private01.java @@ -1,6 +1,5 @@ package com.brianway.learning.java.multithread.synchronize.example2; - /** * Created by Brian on 2016/4/11. */ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadA.java index 2772393..d10c147 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadA.java @@ -3,9 +3,10 @@ /** * Created by Brian on 2016/4/11. */ -public class ThreadA extends Thread{ +public class ThreadA extends Thread { private HasSelfPrivateNum numRef; - public ThreadA(HasSelfPrivateNum numRef){ + + public ThreadA(HasSelfPrivateNum numRef) { super(); this.numRef = numRef; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadB.java index e35b481..95d69a5 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadB.java @@ -3,9 +3,10 @@ /** * Created by Brian on 2016/4/11. */ -public class ThreadB extends Thread{ +public class ThreadB extends Thread { private HasSelfPrivateNum numRef; - public ThreadB(HasSelfPrivateNum numRef){ + + public ThreadB(HasSelfPrivateNum numRef) { super(); this.numRef = numRef; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/MyObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/MyObject.java index 9a3f829..3a9275e 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/MyObject.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/MyObject.java @@ -6,11 +6,11 @@ public class MyObject { synchronized - public void methodA(){ + public void methodA() { try { - System.out.println("begin methodA threadName="+Thread.currentThread().getName()); + System.out.println("begin methodA threadName=" + Thread.currentThread().getName()); Thread.sleep(5000); - System.out.println(Thread.currentThread().getName()+" end"); + System.out.println(Thread.currentThread().getName() + " end"); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/Run3_synchronized01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/Run3_synchronized01.java index d868848..3ec5fbd 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/Run3_synchronized01.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/Run3_synchronized01.java @@ -12,9 +12,9 @@ public class Run3_synchronized01 { public static void main(String[] args) { MyObject object = new MyObject(); ThreadA a = new ThreadA(object); - a.setName("A"); + a.setName("A "); ThreadB b = new ThreadB(object); - b.setName("B"); + b.setName("B "); a.start(); b.start(); } @@ -25,16 +25,16 @@ public void methodA()没加synchronized 输出: begin methodA threadName=B begin methodA threadName=A -A end -B end +A end +B end ------------------- public void methodA()加synchronized 输出: begin methodA threadName=A -A end +A end begin methodA threadName=B -B end +B end */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadA.java index b6efb1a..0cb786e 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadA.java @@ -3,9 +3,10 @@ /** * Created by Brian on 2016/4/12. */ -public class ThreadA extends Thread{ +public class ThreadA extends Thread { private MyObject object; - public ThreadA(MyObject object){ + + public ThreadA(MyObject object) { super(); this.object = object; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadB.java index bc2e353..bd32dda 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadB.java @@ -3,9 +3,10 @@ /** * Created by Brian on 2016/4/12. */ -public class ThreadB extends Thread{ +public class ThreadB extends Thread { private MyObject object; - public ThreadB(MyObject object){ + + public ThreadB(MyObject object) { super(); this.object = object; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/MyObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/MyObject.java index 70accb8..09aa105 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/MyObject.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/MyObject.java @@ -5,22 +5,22 @@ */ public class MyObject { - synchronized public void methodA(){ + synchronized public void methodA() { try { - System.out.println("begin methodA threadName="+Thread.currentThread().getName()); + System.out.println("begin methodA threadName=" + Thread.currentThread().getName()); Thread.sleep(5000); - System.out.println(Thread.currentThread().getName()+" endTime:"+System.currentTimeMillis()); + System.out.println(Thread.currentThread().getName() + " endTime:" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized - public void methodB(){ + public void methodB() { try { - System.out.println("begin methodB threadName="+Thread.currentThread().getName()); + System.out.println("begin methodB threadName=" + Thread.currentThread().getName()); Thread.sleep(5000); - System.out.println(Thread.currentThread().getName()+" endTime:"+System.currentTimeMillis()); + System.out.println(Thread.currentThread().getName() + " endTime:" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadA.java index e213e58..85c1995 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadA.java @@ -3,9 +3,10 @@ /** * Created by Brian on 2016/4/12. */ -public class ThreadA extends Thread{ +public class ThreadA extends Thread { private MyObject object; - public ThreadA(MyObject object){ + + public ThreadA(MyObject object) { super(); this.object = object; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadB.java index 61b5860..0e4b447 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadB.java @@ -3,9 +3,10 @@ /** * Created by Brian on 2016/4/12. */ -public class ThreadB extends Thread{ +public class ThreadB extends Thread { private MyObject object; - public ThreadB(MyObject object){ + + public ThreadB(MyObject object) { super(); this.object = object; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Main.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Main.java index 92c851b..48bf667 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Main.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Main.java @@ -5,10 +5,11 @@ */ public class Main { protected int i = 10; - synchronized public void operateIinMain(){ + + synchronized public void operateIinMain() { try { i--; - System.out.println("main print i="+i); + System.out.println("main print i=" + i); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Run5_lockRein.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Run5_lockRein.java index 6565c54..53ceba0 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Run5_lockRein.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Run5_lockRein.java @@ -10,7 +10,7 @@ */ public class Run5_lockRein { public static void main(String[] args) { - Thread t = new Thread(){ + Thread t = new Thread() { @Override public void run() { Sub sub = new Sub(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Sub.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Sub.java index 445ed67..a950354 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Sub.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Sub.java @@ -3,12 +3,12 @@ /** * Created by Brian on 2016/4/12. */ -public class Sub extends Main{ - synchronized public void operateIinSub(){ +public class Sub extends Main { + synchronized public void operateIinSub() { try { - while (i>0){ + while (i > 0) { i--; - System.out.println("sub print i="+i); + System.out.println("sub print i=" + i); Thread.sleep(100); this.operateIinMain(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Run6_exception.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Run6_exception.java index c0b5660..8ca51b0 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Run6_exception.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Run6_exception.java @@ -13,10 +13,10 @@ public static void main(String[] args) { try { Service service = new Service(); - ThreadA a = new ThreadA("a",service); + ThreadA a = new ThreadA("a", service); a.start(); Thread.sleep(500); - ThreadB b = new ThreadB("b",service); + ThreadB b = new ThreadB("b", service); b.start(); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Service.java index 77c166a..d33d095 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Service.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Service.java @@ -4,19 +4,19 @@ * Created by Brian on 2016/4/12. */ public class Service { - synchronized public void testMethod(){ - if(Thread.currentThread().getName().equals("a")){ - System.out.println("ThreadName="+ Thread.currentThread().getName()+" run beginTime="+System.currentTimeMillis()); + synchronized public void testMethod() { + if (Thread.currentThread().getName().equals("a")) { + System.out.println("ThreadName=" + Thread.currentThread().getName() + " run beginTime=" + System.currentTimeMillis()); int i = 1; - while(i == 1){ - if((""+Math.random()).substring(0,8).equals("0.123456")){ - System.out.println("ThreadName="+ Thread.currentThread().getName()+" run exceptionTime="+System.currentTimeMillis()); + while (i == 1) { + if (("" + Math.random()).substring(0, 8).equals("0.123456")) { + System.out.println("ThreadName=" + Thread.currentThread().getName() + " run exceptionTime=" + System.currentTimeMillis()); Integer.parseInt("a"); } } - }else{ - System.out.println("Thread b run Time="+System.currentTimeMillis()); + } else { + System.out.println("Thread b run Time=" + System.currentTimeMillis()); } } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadA.java index 933a437..d3ecf75 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadA.java @@ -3,7 +3,7 @@ /** * Created by Brian on 2016/4/12. */ -public class ThreadA extends Thread{ +public class ThreadA extends Thread { private Service service; public ThreadA(String name, Service service) { diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadB.java index fc4f458..8c5d51e 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadB.java @@ -3,7 +3,7 @@ /** * Created by Brian on 2016/4/12. */ -public class ThreadB extends Thread{ +public class ThreadB extends Thread { private Service service; public ThreadB(String name, Service service) { diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Main.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Main.java index a0db493..13bd444 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Main.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Main.java @@ -4,11 +4,11 @@ * Created by Brian on 2016/4/12. */ public class Main { - synchronized public void testMethod(){ + synchronized public void testMethod() { try { - System.out.println("threadName= "+Thread.currentThread().getName()+" in main 下一步 sleep begin time ="+System.currentTimeMillis()); + System.out.println("threadName= " + Thread.currentThread().getName() + " in main 下一步 sleep begin time =" + System.currentTimeMillis()); Thread.sleep(5000); - System.out.println("threadName= "+Thread.currentThread().getName()+" in main 下一步 sleep end time ="+System.currentTimeMillis()); + System.out.println("threadName= " + Thread.currentThread().getName() + " in main 下一步 sleep end time =" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/MyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/MyThread.java index 7bb4f1f..a3b3955 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/MyThread.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/MyThread.java @@ -3,11 +3,12 @@ /** * Created by Brian on 2016/4/12. */ -public class MyThread extends Thread{ +public class MyThread extends Thread { private Sub sub; - public MyThread(Sub sub){ + + public MyThread(Sub sub) { super(); - this.sub= sub; + this.sub = sub; } @Override diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Sub.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Sub.java index 3e9976a..d8f2d9f 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Sub.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Sub.java @@ -3,13 +3,13 @@ /** * Created by Brian on 2016/4/12. */ -public class Sub extends Main{ +public class Sub extends Main { //synchronized - public void testMethod(){ + public void testMethod() { try { - System.out.println("threadName= "+Thread.currentThread().getName()+" in sub 下一步 sleep begin time ="+System.currentTimeMillis()); + System.out.println("threadName= " + Thread.currentThread().getName() + " in sub 下一步 sleep begin time =" + System.currentTimeMillis()); Thread.sleep(2000); - System.out.println("threadName= "+Thread.currentThread().getName()+" in sub 下一步 sleep end time ="+System.currentTimeMillis()); + System.out.println("threadName= " + Thread.currentThread().getName() + " in sub 下一步 sleep end time =" + System.currentTimeMillis()); super.testMethod(); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadA.java index a9d3edf..2cbbc78 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadA.java @@ -3,24 +3,26 @@ /** * Created by Brian on 2016/4/12. */ -public class MyThreadA extends Thread{ +public class MyThreadA extends Thread { private TaskA taskA; - public MyThreadA(TaskA taskA){ + + public MyThreadA(TaskA taskA) { super(); this.taskA = taskA; } + @Override public void run() { super.run(); - if(this.getName().equals("a")){ - CommonUtils.beginTime1= System.currentTimeMillis(); + if (this.getName().equals("a")) { + CommonUtils.beginTime1 = System.currentTimeMillis(); taskA.doLongTimeTask(); CommonUtils.endTime1 = System.currentTimeMillis(); - }else if(this.getName().equals("b")){ - CommonUtils.beginTime2= System.currentTimeMillis(); + } else if (this.getName().equals("b")) { + CommonUtils.beginTime2 = System.currentTimeMillis(); taskA.doLongTimeTask(); CommonUtils.endTime2 = System.currentTimeMillis(); - }else{ + } else { System.out.println("unexpected name"); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadB.java index 4d5ab4d..5f77112 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadB.java @@ -3,24 +3,26 @@ /** * Created by Brian on 2016/4/12. */ -public class MyThreadB extends Thread{ +public class MyThreadB extends Thread { private TaskB taskB; - public MyThreadB(TaskB taskB){ + + public MyThreadB(TaskB taskB) { super(); this.taskB = taskB; } + @Override public void run() { super.run(); - if(this.getName().equals("c")){ - CommonUtils.beginTime1= System.currentTimeMillis(); + if (this.getName().equals("c")) { + CommonUtils.beginTime1 = System.currentTimeMillis(); taskB.doLongTimeTask(); CommonUtils.endTime1 = System.currentTimeMillis(); - }else if(this.getName().equals("d")){ - CommonUtils.beginTime2= System.currentTimeMillis(); + } else if (this.getName().equals("d")) { + CommonUtils.beginTime2 = System.currentTimeMillis(); taskB.doLongTimeTask(); CommonUtils.endTime2 = System.currentTimeMillis(); - }else{ + } else { System.out.println("unexpected name"); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized01.java index e810f93..68195e1 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized01.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized01.java @@ -11,11 +11,11 @@ public class Run8_synchronized01 { public static void main(String[] args) { TaskA taskA = new TaskA(); - MyThreadA thread1 =new MyThreadA(taskA); + MyThreadA thread1 = new MyThreadA(taskA); thread1.setName("a"); thread1.start(); - MyThreadA thread2 =new MyThreadA(taskA); + MyThreadA thread2 = new MyThreadA(taskA); thread2.setName("b"); thread2.start(); @@ -25,12 +25,11 @@ public static void main(String[] args) { e.printStackTrace(); } - long beginTime = CommonUtils.beginTime2CommonUtils.endTime2?CommonUtils.endTime1:CommonUtils.endTime2; - System.out.println("耗时:"+(endTime-beginTime)/1000); + long beginTime = CommonUtils.beginTime2 < CommonUtils.beginTime1 ? CommonUtils.beginTime2 : CommonUtils.beginTime1; + long endTime = CommonUtils.endTime1 > CommonUtils.endTime2 ? CommonUtils.endTime1 : CommonUtils.endTime2; + System.out.println("耗时:" + (endTime - beginTime) / 1000); } - } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized02.java index 2a2a1ba..6f2dde5 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized02.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized02.java @@ -7,16 +7,16 @@ /** * P76 * 同步代码块解决同步方法的弊端 - * 但输出并不是两个c,两个d,原因? + * TODO 但输出并不是两个c,两个d,原因? */ public class Run8_synchronized02 { public static void main(String[] args) { TaskB taskB = new TaskB(); - MyThreadB thread1 =new MyThreadB(taskB); + MyThreadB thread1 = new MyThreadB(taskB); thread1.setName("c"); thread1.start(); - MyThreadB thread2 =new MyThreadB(taskB); + MyThreadB thread2 = new MyThreadB(taskB); thread2.setName("d"); thread2.start(); @@ -26,9 +26,9 @@ public static void main(String[] args) { e.printStackTrace(); } - long beginTime = CommonUtils.beginTime2CommonUtils.endTime2?CommonUtils.endTime1:CommonUtils.endTime2; - System.out.println("耗时:"+(endTime-beginTime)/1000); + long beginTime = CommonUtils.beginTime2 < CommonUtils.beginTime1 ? CommonUtils.beginTime2 : CommonUtils.beginTime1; + long endTime = CommonUtils.endTime1 > CommonUtils.endTime2 ? CommonUtils.endTime1 : CommonUtils.endTime2; + System.out.println("耗时:" + (endTime - beginTime) / 1000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskA.java index a2fe05f..a2bdead 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskA.java @@ -7,12 +7,12 @@ public class TaskA { private String getData1; private String getData2; - public synchronized void doLongTimeTask(){ + public synchronized void doLongTimeTask() { try { System.out.println("begin task"); Thread.sleep(3000); - getData1 = "长时间处理任务后从远程返回的值1 threadName="+Thread.currentThread().getName(); - getData2 = "长时间处理任务后从远程返回的值2 threadName="+Thread.currentThread().getName(); + getData1 = "长时间处理任务后从远程返回的值1 threadName=" + Thread.currentThread().getName(); + getData2 = "长时间处理任务后从远程返回的值2 threadName=" + Thread.currentThread().getName(); System.out.println(getData1); System.out.println(getData2); System.out.println("end task"); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskB.java index 0bc640b..5cfc9b4 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskB.java @@ -7,13 +7,13 @@ public class TaskB { private String getData1; private String getData2; - public void doLongTimeTask(){ + public void doLongTimeTask() { try { System.out.println("begin task"); Thread.sleep(3000); - String privateGetData1 = "长时间处理任务后从远程返回的值1 threadName="+Thread.currentThread().getName(); - String privateGetData2 = "长时间处理任务后从远程返回的值2 threadName="+Thread.currentThread().getName(); - synchronized (this){ + String privateGetData1 = "长时间处理任务后从远程返回的值1 threadName=" + Thread.currentThread().getName(); + String privateGetData2 = "长时间处理任务后从远程返回的值2 threadName=" + Thread.currentThread().getName(); + synchronized (this) { //System.out.println("切换到线程begin:"+Thread.currentThread().getName()); getData1 = privateGetData1; getData2 = privateGetData2; diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject1.java index b308bed..c30a6c3 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject1.java @@ -4,9 +4,9 @@ * Created by Brian on 2016/4/12. */ public class MyObject1 extends MyObject { - synchronized public void speedPrintString(){ - System.out.println("speedPrintString ____getLock time="+System.currentTimeMillis()+ " run ThreadName="+Thread.currentThread().getName()); + synchronized public void speedPrintString() { + System.out.println("speedPrintString ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); System.out.println("*******************"); - System.out.println("speedPrintString releaseLock time="+System.currentTimeMillis()+ " run ThreadName="+Thread.currentThread().getName()); + System.out.println("speedPrintString releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject2.java index d9474f4..c73a380 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject2.java @@ -3,12 +3,12 @@ /** * Created by Brian on 2016/4/12. */ -public class MyObject2 extends MyObject{ - public void speedPrintString(){ - synchronized (this){ - System.out.println("speedPrintString ____getLock time="+System.currentTimeMillis()+ " run ThreadName="+Thread.currentThread().getName()); +public class MyObject2 extends MyObject { + public void speedPrintString() { + synchronized (this) { + System.out.println("speedPrintString ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); System.out.println("*******************"); - System.out.println("speedPrintString releaseLock time="+System.currentTimeMillis()+ " run ThreadName="+Thread.currentThread().getName()); + System.out.println("speedPrintString releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyThread.java index bd3cb2f..989e92a 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyThread.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyThread.java @@ -3,11 +3,11 @@ /** * Created by Brian on 2016/4/12. */ -public class MyThread extends Thread{ +public class MyThread extends Thread { private Service service; private MyObject object; - public MyThread(Service service,MyObject object) { + public MyThread(Service service, MyObject object) { super(); this.object = object; this.service = service; diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01.java index 89cb151..b5994f4 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01.java @@ -9,7 +9,7 @@ * synchronized(非this对象x)的三个结论 * 1)当多个线程同时执行synchronized(x){}同步代码块时呈现效果 * 2)当其他线程执行x对象中synchronized同步方法时呈同步效果 - * 3)当其他线程执行x对象里面的ynchronized(this)代码块时,也呈现同步效果 + * 3)当其他线程执行x对象里面的synchronized(this)代码块时,也呈现同步效果 * 验证结论1: * 当多个线程同时执行synchronized(x){}同步代码块时呈现效果 */ @@ -18,10 +18,10 @@ public static void main(String[] args) { Service service = new Service(); MyObject object = new MyObject(); - MyThread a = new MyThread(service,object); + MyThread a = new MyThread(service, object); a.setName("a"); a.start(); - MyThread b = new MyThread(service,object); + MyThread b = new MyThread(service, object); b.setName("b"); b.start(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01_twoObjects.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01_twoObjects.java index 4c5ccf5..98d311b 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01_twoObjects.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01_twoObjects.java @@ -14,10 +14,10 @@ public static void main(String[] args) { MyObject object1 = new MyObject(); MyObject object2 = new MyObject(); - MyThread a = new MyThread(service,object1); + MyThread a = new MyThread(service, object1); a.setName("a"); a.start(); - MyThread b = new MyThread(service,object2); + MyThread b = new MyThread(service, object2); b.setName("b"); b.start(); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized02.java index deef8bb..9db4ea8 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized02.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized02.java @@ -9,7 +9,7 @@ * synchronized(非this对象x)的三个结论 * 1)当多个线程同时执行synchronized(x){}同步代码块时呈现效果 * 2)当其他线程执行x对象中synchronized同步方法时呈同步效果 - * 3)当其他线程执行x对象里面的ynchronized(this)代码块时,也呈现同步效果 + * 3)当其他线程执行x对象里面的synchronized(this)代码块时,也呈现同步效果 * 验证结论2: * 当其他线程执行x对象中synchronized同步方法时呈同步效果 */ @@ -18,7 +18,7 @@ public static void main(String[] args) { Service service = new Service(); MyObject1 object1 = new MyObject1(); - MyThread a = new MyThread(service,object1); + MyThread a = new MyThread(service, object1); a.setName("a"); a.start(); Thread1 b = new Thread1(object1); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized03.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized03.java index 4656f88..26827c3 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized03.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized03.java @@ -9,7 +9,7 @@ * synchronized(非this对象x)的三个结论 * 1)当多个线程同时执行synchronized(x){}同步代码块时呈现效果 * 2)当其他线程执行x对象中synchronized同步方法时呈同步效果 - * 3)当其他线程执行x对象里面的ynchronized(this)代码块时,也呈现同步效果 + * 3)当其他线程执行x对象里面的synchronized(this)代码块时,也呈现同步效果 * 验证结论1: * 当其他线程执行x对象里面的ynchronized(this)代码块时,也呈现同步效果 */ @@ -19,7 +19,7 @@ public static void main(String[] args) { Service service = new Service(); MyObject2 object2 = new MyObject2(); - MyThread a = new MyThread(service,object2); + MyThread a = new MyThread(service, object2); a.setName("a"); a.start(); Thread2 b = new Thread2(object2); diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Service.java index d021668..507a336 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Service.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Service.java @@ -4,12 +4,12 @@ * Created by Brian on 2016/4/12. */ public class Service { - public void testMethod1(MyObject object){ - synchronized (object){ + public void testMethod1(MyObject object) { + synchronized (object) { try { - System.out.println("testMethod1 ____getLock time="+System.currentTimeMillis()+ " run ThreadName="+Thread.currentThread().getName()); + System.out.println("testMethod1 ____getLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); Thread.sleep(2000); - System.out.println("testMethod1 releaseLock time="+System.currentTimeMillis()+ " run ThreadName="+Thread.currentThread().getName()); + System.out.println("testMethod1 releaseLock time=" + System.currentTimeMillis() + " run ThreadName=" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread1.java index c0a2eb2..bc4be32 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread1.java @@ -3,10 +3,9 @@ /** * Created by Brian on 2016/4/12. */ -public class Thread1 extends Thread{ +public class Thread1 extends Thread { private MyObject1 object1; - public Thread1(MyObject1 object1) { this.object1 = object1; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread2.java index 31ef386..34855b4 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread2.java @@ -3,10 +3,9 @@ /** * Created by Brian on 2016/4/12. */ -public class Thread2 extends Thread{ +public class Thread2 extends Thread { private MyObject2 object2; - public Thread2(MyObject2 object2) { this.object2 = object2; } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/MyTask.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/MyTask.java index ecb1791..12c783c 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/MyTask.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/MyTask.java @@ -6,9 +6,9 @@ /** * Created by Brian on 2016/4/15. */ -public class MyTask extends TimerTask{ +public class MyTask extends TimerTask { @Override public void run() { - System.out.println("任务执行了,时间为:"+new Date()); + System.out.println("任务执行了,时间为:" + new Date()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer1.java index 401fa4a..e269b2f 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer1.java @@ -15,14 +15,14 @@ */ public class Run1_timer1 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.SECOND,5); + calendar.add(Calendar.SECOND, 5); Date runDate = calendar.getTime(); MyTask task = new MyTask(); Timer timer = new Timer(); - timer.schedule(task,runDate); + timer.schedule(task, runDate); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer2.java index 16e1e5a..8f77089 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer2.java @@ -16,14 +16,14 @@ */ public class Run1_timer2 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.SECOND,5); + calendar.add(Calendar.SECOND, 5); Date runDate = calendar.getTime(); MyTask task = new MyTask(); Timer timer = new Timer(true);//守护线程 - timer.schedule(task,runDate); + timer.schedule(task, runDate); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer3.java index 0ff33f2..5163053 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer3.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer3.java @@ -14,14 +14,14 @@ */ public class Run1_timer3 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.SECOND,calendar.get(Calendar.SECOND)-10); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 10); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); MyTask task = new MyTask(); Timer timer = new Timer(); - timer.schedule(task,runDate); + timer.schedule(task, runDate); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer4.java index ae23c25..a686757 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer4.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer4.java @@ -14,22 +14,22 @@ */ public class Run1_timer4 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.SECOND,5); + calendar.add(Calendar.SECOND, 5); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); Calendar calendar2 = Calendar.getInstance(); - calendar.add(Calendar.SECOND,10); + calendar.add(Calendar.SECOND, 10); Date runDate2 = calendar2.getTime(); - System.out.println("计划时间为:"+ runDate2); + System.out.println("计划时间为:" + runDate2); MyTask task1 = new MyTask(); MyTask task2 = new MyTask(); Timer timer = new Timer(); - timer.schedule(task1,runDate); - timer.schedule(task2,runDate); + timer.schedule(task1, runDate); + timer.schedule(task2, runDate); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer5.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer5.java index 8ce959a..ff7c9bc 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer5.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer5.java @@ -15,21 +15,21 @@ */ public class Run1_timer5 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); - System.out.println("A计划时间为:"+ runDate); + System.out.println("A计划时间为:" + runDate); Calendar calendar2 = Calendar.getInstance(); - calendar2.add(Calendar.SECOND,5); + calendar2.add(Calendar.SECOND, 5); Date runDate2 = calendar2.getTime(); - System.out.println("B计划时间为:"+ runDate2); + System.out.println("B计划时间为:" + runDate2); TaskA task1 = new TaskA(); TaskB task2 = new TaskB(); Timer timer = new Timer(); - timer.schedule(task1,runDate); - timer.schedule(task2,runDate); + timer.schedule(task1, runDate); + timer.schedule(task2, runDate); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskA.java index 9030040..9b142f8 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskA.java @@ -6,13 +6,13 @@ /** * Created by Brian on 2016/4/15. */ -public class TaskA extends TimerTask{ +public class TaskA extends TimerTask { @Override public void run() { try { - System.out.println("A begin timer="+new Date()); + System.out.println("A begin timer=" + new Date()); Thread.sleep(10000); - System.out.println("A end timer="+new Date()); + System.out.println("A end timer=" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskB.java index adb0bd0..6997f42 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskB.java @@ -6,10 +6,10 @@ /** * Created by Brian on 2016/4/15. */ -public class TaskB extends TimerTask{ +public class TaskB extends TimerTask { @Override public void run() { - System.out.println("B begin timer="+new Date()); - System.out.println("B end timer="+new Date()); + System.out.println("B begin timer=" + new Date()); + System.out.println("B end timer=" + new Date()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/MyTask.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/MyTask.java index 7c2a555..c087214 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/MyTask.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/MyTask.java @@ -6,9 +6,9 @@ /** * Created by Brian on 2016/4/15. */ -public class MyTask extends TimerTask{ +public class MyTask extends TimerTask { @Override public void run() { - System.out.println("任务执行了,时间为:"+new Date()); + System.out.println("任务执行了,时间为:" + new Date()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period1.java index 1c50401..a348ba9 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period1.java @@ -1,8 +1,5 @@ package com.brianway.learning.java.multithread.timer.example2; -import com.brianway.learning.java.multithread.timer.example1.TaskA; -import com.brianway.learning.java.multithread.timer.example1.TaskB; - import java.util.Calendar; import java.util.Date; import java.util.Timer; @@ -17,15 +14,15 @@ */ public class Run2_period1 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.SECOND,10); + calendar.add(Calendar.SECOND, 10); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); MyTask task = new MyTask(); Timer timer = new Timer(); - timer.schedule(task,runDate,4000); + timer.schedule(task, runDate, 4000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period2.java index 5ac84d4..64c6ea4 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period2.java @@ -14,15 +14,15 @@ */ public class Run2_period2 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.SECOND,calendar.get(Calendar.SECOND)-10); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 10); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); MyTask task = new MyTask(); Timer timer = new Timer(); - timer.schedule(task,runDate,4000); + timer.schedule(task, runDate, 4000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period3.java index 3f91fe4..a4fb9b0 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period3.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period3.java @@ -14,15 +14,15 @@ */ public class Run2_period3 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.SECOND,10); + calendar.add(Calendar.SECOND, 10); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); TaskA task = new TaskA(); Timer timer = new Timer(); - timer.schedule(task,runDate,3000); + timer.schedule(task, runDate, 3000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/TaskA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/TaskA.java index 01373f6..bc5d902 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/TaskA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/TaskA.java @@ -6,13 +6,13 @@ /** * Created by Brian on 2016/4/15. */ -public class TaskA extends TimerTask{ +public class TaskA extends TimerTask { @Override public void run() { try { - System.out.println("A begin timer="+new Date()); + System.out.println("A begin timer=" + new Date()); Thread.sleep(5000); - System.out.println("A end timer="+new Date()); + System.out.println("A end timer=" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/MyTask.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/MyTask.java index a8e7202..d539ada 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/MyTask.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/MyTask.java @@ -14,6 +14,6 @@ public MyTask(int i) { @Override public void run() { - System.out.println("第"+i+"次没有被cancel取消"); + System.out.println("第" + i + "次没有被cancel取消"); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel1.java index d8128be..b6b75d9 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel1.java @@ -15,16 +15,16 @@ */ public class Run3_cancel1 { public static void main(String[] args) { - System.out.println("当前时间为:"+new Date()); + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); TaskA task1 = new TaskA(); - TaskB task2 =new TaskB(); + TaskB task2 = new TaskB(); Timer timer = new Timer(); - timer.schedule(task1,runDate,4000); - timer.schedule(task2,runDate,4000); + timer.schedule(task1, runDate, 4000); + timer.schedule(task2, runDate, 4000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel2.java index cb9cb53..466be39 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel2.java @@ -4,8 +4,6 @@ import java.util.Date; import java.util.Timer; - - /** * Created by Brian on 2016/4/15. */ @@ -16,17 +14,17 @@ * 全部任务被清除,且进程被销毁 */ public class Run3_cancel2 { - public static void main(String[] args) throws InterruptedException{ - System.out.println("当前时间为:"+new Date()); + public static void main(String[] args) throws InterruptedException { + System.out.println("当前时间为:" + new Date()); Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); - System.out.println("计划时间为:"+ runDate); + System.out.println("计划时间为:" + runDate); TaskA2 task1 = new TaskA2(); - TaskB2 task2 =new TaskB2(); + TaskB2 task2 = new TaskB2(); Timer timer = new Timer(); - timer.schedule(task1,runDate,2000); - timer.schedule(task2,runDate,2000); + timer.schedule(task1, runDate, 2000); + timer.schedule(task2, runDate, 2000); Thread.sleep(10000); timer.cancel(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel3.java index c79febc..df103e1 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel3.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel3.java @@ -4,8 +4,6 @@ import java.util.Date; import java.util.Timer; - - /** * Created by Brian on 2016/4/15. */ @@ -16,16 +14,16 @@ * 有时不一定会停止计划任务,(见源码,queue锁) */ public class Run3_cancel3 { - public static void main(String[] args) throws InterruptedException{ - int i =0; + public static void main(String[] args) throws InterruptedException { + int i = 0; Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); - while (true){ + while (true) { i++; Timer timer = new Timer(); MyTask task = new MyTask(i); - timer.schedule(task,runDate); + timer.schedule(task, runDate); timer.cancel(); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA.java index e173713..f93c6bb 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA.java @@ -6,10 +6,10 @@ /** * Created by Brian on 2016/4/15. */ -public class TaskA extends TimerTask{ +public class TaskA extends TimerTask { @Override public void run() { - System.out.println("A run timer="+new Date()); + System.out.println("A run timer=" + new Date()); this.cancel(); System.out.println("A任务自己移除自己"); } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA2.java index c452727..430deed 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA2.java @@ -6,9 +6,9 @@ /** * Created by Brian on 2016/4/15. */ -public class TaskA2 extends TimerTask{ +public class TaskA2 extends TimerTask { @Override public void run() { - System.out.println("A run timer="+new Date()); + System.out.println("A run timer=" + new Date()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB.java index 5c63c45..996dbb5 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB.java @@ -6,9 +6,9 @@ /** * Created by brian on 2016/4/15. */ -public class TaskB extends TimerTask{ +public class TaskB extends TimerTask { @Override public void run() { - System.out.println("B run timer="+new Date()); + System.out.println("B run timer=" + new Date()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB2.java index dcb96ac..63ad2aa 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB2.java @@ -6,9 +6,9 @@ /** * Created by Brian on 2016/4/15. */ -public class TaskB2 extends TimerTask{ +public class TaskB2 extends TimerTask { @Override public void run() { - System.out.println("B run timer="+new Date()); + System.out.println("B run timer=" + new Date()); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule1.java index 47b22c9..feeeca8 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule1.java @@ -13,18 +13,18 @@ * schedule(TimerTask task, long delay)方法 */ public class Run4_schedule1 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { - System.out.println("运行了!时间为:"+new Date()); + System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args) { MyTask task = new MyTask(); Timer timer = new Timer(); - System.out.println("当前时间:"+new Date()); - timer.schedule(task,7000); + System.out.println("当前时间:" + new Date()); + timer.schedule(task, 7000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule2.java index e82c4c1..a841364 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule2.java @@ -13,18 +13,18 @@ * schedule(TimerTask task, long delay, long period)方法 */ public class Run4_schedule2 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { - System.out.println("运行了!时间为:"+new Date()); + System.out.println("运行了!时间为:" + new Date()); } } public static void main(String[] args) { MyTask task = new MyTask(); Timer timer = new Timer(); - System.out.println("当前时间:"+new Date()); - timer.schedule(task,2000,1000); + System.out.println("当前时间:" + new Date()); + timer.schedule(task, 2000, 1000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule3.java index 3fab0bc..337e598 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule3.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule3.java @@ -16,13 +16,13 @@ * 不延时的情况下,若执行任务未被延时,下次执行任务的开始时间是上一次任务的开始时间加上period */ public class Run4_schedule3 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(1000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -34,7 +34,7 @@ public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); Timer timer = new Timer(); - timer.schedule(task,runDate,3000); + timer.schedule(task, runDate, 3000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule4.java index 15a09b5..2ea64c9 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule4.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule4.java @@ -4,7 +4,6 @@ * Created by brian on 2016/4/15. */ - import java.util.Timer; import java.util.TimerTask; @@ -15,13 +14,13 @@ * 不延时的情况下,若执行任务未被延时,第一次执行是任务开始+delay,下次执行任务的开始时间是上一次任务的开始时间加上period */ public class Run4_schedule4 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(1000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -30,9 +29,9 @@ public void run() { public static void main(String[] args) { MyTask task = new MyTask(); - System.out.println("当前时间:"+System.currentTimeMillis()); + System.out.println("当前时间:" + System.currentTimeMillis()); Timer timer = new Timer(); - timer.schedule(task,3000,4000); + timer.schedule(task, 3000, 4000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule5.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule5.java index b6e3aa8..a01c942 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule5.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule5.java @@ -16,13 +16,13 @@ * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 */ public class Run4_schedule5 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(5000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -34,7 +34,7 @@ public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); Timer timer = new Timer(); - timer.schedule(task,runDate,2000); + timer.schedule(task, runDate, 2000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule6.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule6.java index b8532f9..6414872 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule6.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule6.java @@ -4,7 +4,6 @@ * Created by brian on 2016/4/15. */ - import java.util.Timer; import java.util.TimerTask; @@ -15,13 +14,13 @@ * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 */ public class Run4_schedule6 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(5000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -30,9 +29,9 @@ public void run() { public static void main(String[] args) { MyTask task = new MyTask(); - System.out.println("当前时间:"+System.currentTimeMillis()); + System.out.println("当前时间:" + System.currentTimeMillis()); Timer timer = new Timer(); - timer.schedule(task,3000,2000); + timer.schedule(task, 3000, 2000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate1.java index fed27c7..1dac553 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate1.java @@ -16,13 +16,13 @@ * 不延时的情况下,若执行任务未被延时,下次执行任务的开始时间是上一次任务的开始时间加上period */ public class Run4_scheduleAtFixedRate1 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(1000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -34,7 +34,7 @@ public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); Timer timer = new Timer(); - timer.scheduleAtFixedRate(task,runDate,3000); + timer.scheduleAtFixedRate(task, runDate, 3000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate2.java index a27f004..8b1ba32 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate2.java @@ -4,7 +4,6 @@ * Created by brian on 2016/4/15. */ - import java.util.Timer; import java.util.TimerTask; @@ -15,13 +14,13 @@ * 不延时的情况下,若执行任务未被延时,第一次执行是任务开始+delay,下次执行任务的开始时间是上一次任务的开始时间加上period */ public class Run4_scheduleAtFixedRate2 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(1000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -30,9 +29,9 @@ public void run() { public static void main(String[] args) { MyTask task = new MyTask(); - System.out.println("当前时间:"+System.currentTimeMillis()); + System.out.println("当前时间:" + System.currentTimeMillis()); Timer timer = new Timer(); - timer.scheduleAtFixedRate(task,3000,4000); + timer.scheduleAtFixedRate(task, 3000, 4000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate3.java index 9ad09a8..b01be92 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate3.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate3.java @@ -16,13 +16,13 @@ * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 */ public class Run4_scheduleAtFixedRate3 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(5000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -34,7 +34,7 @@ public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); Date runDate = calendar.getTime(); Timer timer = new Timer(); - timer.scheduleAtFixedRate(task,runDate,2000); + timer.scheduleAtFixedRate(task, runDate, 2000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate4.java index 22d711b..d525115 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate4.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate4.java @@ -4,7 +4,6 @@ * Created by brian on 2016/4/15. */ - import java.util.Timer; import java.util.TimerTask; @@ -15,13 +14,13 @@ * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 */ public class Run4_scheduleAtFixedRate4 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { try { - System.out.println("begin timer="+ System.currentTimeMillis()); + System.out.println("begin timer=" + System.currentTimeMillis()); Thread.sleep(5000); - System.out.println("end timer="+ System.currentTimeMillis()); + System.out.println("end timer=" + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } @@ -30,9 +29,9 @@ public void run() { public static void main(String[] args) { MyTask task = new MyTask(); - System.out.println("当前时间:"+System.currentTimeMillis()); + System.out.println("当前时间:" + System.currentTimeMillis()); Timer timer = new Timer(); - timer.scheduleAtFixedRate(task,3000,2000); + timer.scheduleAtFixedRate(task, 3000, 2000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_1.java index b1f089b..2bf97ad 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_1.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_1.java @@ -4,7 +4,6 @@ * Created by brian on 2016/4/15. */ - import java.util.Calendar; import java.util.Date; import java.util.Timer; @@ -15,23 +14,23 @@ * schedule不具有追赶执行性 */ public class Run4_schedule_vs_scheduleAtFixedRate_1 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { - System.out.println("begin timer="+new Date()); - System.out.println("end timer="+new Date()); + System.out.println("begin timer=" + new Date()); + System.out.println("end timer=" + new Date()); } } public static void main(String[] args) { MyTask task = new MyTask(); - System.out.println("现在执行时间:"+new Date()); + System.out.println("现在执行时间:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.SECOND,calendar.get(Calendar.SECOND)-20); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 20); Date runDate = calendar.getTime(); - System.out.println("计划执行时间:"+ runDate); + System.out.println("计划执行时间:" + runDate); Timer timer = new Timer(); - timer.schedule(task,runDate,2000); + timer.schedule(task, runDate, 2000); } } diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_2.java index 4d34a74..a493c8a 100644 --- a/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_2.java +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_2.java @@ -4,7 +4,6 @@ * Created by brian on 2016/4/15. */ - import java.util.Calendar; import java.util.Date; import java.util.Timer; @@ -15,23 +14,23 @@ * scheduleAtFixedRate具有追赶执行性 */ public class Run4_schedule_vs_scheduleAtFixedRate_2 { - static public class MyTask extends TimerTask{ + static public class MyTask extends TimerTask { @Override public void run() { - System.out.println("begin timer="+new Date()); - System.out.println("end timer="+new Date()); + System.out.println("begin timer=" + new Date()); + System.out.println("end timer=" + new Date()); } } public static void main(String[] args) { MyTask task = new MyTask(); - System.out.println("现在执行时间:"+new Date()); + System.out.println("现在执行时间:" + new Date()); Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.SECOND,calendar.get(Calendar.SECOND)-20); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 20); Date runDate = calendar.getTime(); - System.out.println("计划执行时间:"+ runDate); + System.out.println("计划执行时间:" + runDate); Timer timer = new Timer(); - timer.scheduleAtFixedRate(task,runDate,2000); + timer.scheduleAtFixedRate(task, runDate, 2000); } } diff --git a/java8/README.md b/java8/README.md new file mode 100644 index 0000000..542462c --- /dev/null +++ b/java8/README.md @@ -0,0 +1,86 @@ +# Java 8 新特性 + +阅读《Java 8 in Action》一书的简单整理 + +源码参考了 **java8/Java8InAction**:[https://github.com/java8/Java8InAction](https://github.com/java8/Java8InAction) + +## lambda 表达式 + +- FilteringApples: 传递代码的例子,展示方法引用和 Lambda + + +## steam API + +- Dish: 菜肴类,有一个静态属性的菜肴列表 +- StreamBasic: 指令式和函数式分别挑选低热量食物名 +- StreamOperation: 流操作(中间操作和终端操作) +- Laziness: 流操作-中间操作 +- BuildingStreams: 构建流,从值序列,数组,文件来创建流。斐波拉切数列的几种生成方法 + + +使用流 + +- Filtering: 筛选(谓词筛选:filter;筛选互异的元素:distinct;忽略头几个元素:limit;截短至指定长度:skip) +- Mapping: 映射 +- Finding: 查找和匹配 +- Reducing: 归约 +- PuttingIntoPractice: 各种流操作的使用示例 +- NumericStreams: 数值流(原始类型特化,数值范围) + +用流收集数据 + +- Summarizing: 归约和汇总 +- Reducing: 收集器的灵活性,以不同的方法执行相同的操作 +- Grouping: 分组 +- Partitioning: 分区 +- GroupingTransactions: 分别使用指令式和函数式进行分组 +- ToListCollector: 自定义 ToListCollector,以及进行自定义收集而不去实现 Collector +- PartitionPrimeNumbers: 将数字按质数和非质数分区;Collector 详解 +- CollectorHarness: 比较收集器的性能 + + +并行数据处理 + +- ParallelStreamsHarness: 测量流性能 +- ParallelStreams: 并行流计算 1~n 的和,分别使用指令式,串行迭代流,并行迭代流,基本类型流,有副作用的流 +- ForkJoinSumCalculator: 使用分支/合并框架执行并行求和 +- WordCount: Spliterator: splitable iterator + +## 高效 Java 8 编程 + +- StrategyMain: 策略模式 +- TemplateMain: 模版方法 +- ObserverMain: 观察者模式 +- ChainOfResponsibilityMain: 责任链模式 +- FactoryMain: 工厂模式 +- Debugging: 查看栈跟踪 +- Peek: 使用日志调试 +- Ambiguous: 默认方法解决冲突 + + +Optional + +- Car,Insurance,Person: 模型类 +- OptionalMain: ptional 用法(map,flatMap,filter) +- OptionalInAction: 使用 Optional 实战示例 +- ReadPositiveIntParam: 使用 Optional 示例 + +CompletableFuture + +- v1/Shop: 商店类第一版,没有折扣 +- v1/ShopMain: 使用异步 API 的使用示例 +- v1/BestPriceFinder: 通过不同的方案实现价格查询:顺序流,并行流,CompletableFuture +- v1/BestPriceFinderMain: 测试每种实现方案的执行时间 + +- AsyncShop: 使用工厂方法 supplyAsync 创建 CompletableFuture +- AsyncShopClient: 演示错误处理 +- ExchangeService: 货币兑换类 +- Discount: 折扣类 +- Quote: 解析商店返回的字符串 +- Shop: 商店类,报价按照 `name:price:code` 的格式 +- BestPriceFinder: 添加折扣后的版本 +- BestPriceFinderMain: 测试每种实现方案的执行时间 + +时间和日期 + +- DateTimeExamples: 新的时间和日期 API 示例 \ No newline at end of file diff --git a/java8/pom.xml b/java8/pom.xml new file mode 100644 index 0000000..6868bb2 --- /dev/null +++ b/java8/pom.xml @@ -0,0 +1,21 @@ + + + + java-learning + com.brianway.learning.java + 1.0-SNAPSHOT + + 4.0.0 + + java8 + + + + junit + junit + + + + \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/Ambiguous.java b/java8/src/main/java/com/brianway/learning/java8/effective/Ambiguous.java new file mode 100644 index 0000000..5c43b5d --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/Ambiguous.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java8.effective; + +/** + * 默认方法解决冲突 + */ +public class Ambiguous { + + public static void main(String... args) { + new C().hello(); + } + + interface A { + default void hello() { + System.out.println("Hello from A"); + } + } + + interface B { + default void hello() { + System.out.println("Hello from B"); + } + } + + static class C implements B, A { + public void hello() { + A.super.hello();// Java 8 引入的新语法: X.super.m(...) + // 其中 X 为希望调用 m 方法所在的父接口 + } + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/AsyncShop.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/AsyncShop.java new file mode 100644 index 0000000..d33bcef --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/AsyncShop.java @@ -0,0 +1,48 @@ +package com.brianway.learning.java8.effective.async; + +import static com.brianway.learning.java8.effective.async.Util.delay; +import static com.brianway.learning.java8.effective.async.Util.format; + +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +/** + * 使用工厂方法 supplyAsync 创建 CompletableFuture + */ +public class AsyncShop { + + private final String name; + private final Random random; + + public AsyncShop(String name) { + this.name = name; + random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); + } + + public Future getPrice(String product) { +/* // 抛出 CompletableFuture 内的异常 + CompletableFuture futurePrice = new CompletableFuture<>(); + new Thread( () -> { + try { + double price = calculatePrice(product); + futurePrice.complete(price); + } catch (Exception ex) { + futurePrice.completeExceptionally(ex); + } + }).start(); + return futurePrice; +*/ + // 使用工厂方法 + return CompletableFuture.supplyAsync(() -> calculatePrice(product)); + } + + private double calculatePrice(String product) { + delay(); + if (true) { + throw new RuntimeException("product not available"); + } + return format(random.nextDouble() * product.charAt(0) + product.charAt(1)); + } + +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/AsyncShopClient.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/AsyncShopClient.java new file mode 100644 index 0000000..e9c6ce5 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/AsyncShopClient.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java8.effective.async; + +import java.util.concurrent.Future; + +/** + * 演示错误处理 + */ +public class AsyncShopClient { + + public static void main(String[] args) { + AsyncShop shop = new AsyncShop("BestShop"); + long start = System.nanoTime(); + Future futurePrice = shop.getPrice("myPhone"); + long incocationTime = ((System.nanoTime() - start) / 1_000_000); + System.out.println("Invocation returned after " + incocationTime + " msecs"); + try { + System.out.println("Price is " + futurePrice.get()); + } catch (Exception e) { + throw new RuntimeException(e); + } + long retrivalTime = ((System.nanoTime() - start) / 1_000_000); + System.out.println("Price returned after " + retrivalTime + " msecs"); + } +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/BestPriceFinder.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/BestPriceFinder.java new file mode 100644 index 0000000..808a13c --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/BestPriceFinder.java @@ -0,0 +1,85 @@ +package com.brianway.learning.java8.effective.async; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 添加折扣后的版本 + * 构造同步和异步操作 + */ +public class BestPriceFinder { + + private final List shops = Arrays.asList(new Shop("BestPrice"), + new Shop("LetsSaveBig"), + new Shop("MyFavoriteShop"), + new Shop("BuyItAll"), + new Shop("ShopEasy")); + + private final Executor executor = Executors.newFixedThreadPool(shops.size(), new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + } + }); + + public List findPricesSequential(String product) { + return shops.stream() + .map(shop -> shop.getPrice(product)) + .map(Quote::parse) + .map(Discount::applyDiscount) + .collect(Collectors.toList()); + } + + public List findPricesParallel(String product) { + return shops.parallelStream() + .map(shop -> shop.getPrice(product)) + .map(Quote::parse) + .map(Discount::applyDiscount) + .collect(Collectors.toList()); + } + + public List findPricesFuture(String product) { + List> priceFutures = findPricesStream(product) + .collect(Collectors.toList()); + + return priceFutures.stream() + .map(CompletableFuture::join) + .collect(Collectors.toList()); + } + + /** + * 分了三步: + * 1. 获取价格 + * 2. 解析报价 + * 3. 为计算折扣价格构造 Future + */ + public Stream> findPricesStream(String product) { + return shops.stream() + .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor)) + .map(future -> future.thenApply(Quote::parse)) + .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync( + () -> Discount.applyDiscount(quote), executor))); + } + + /** + * 响应 CompletableFuture 的 completion 事件 + * 把 Util 类中的 delay 调一下效果更明显 + */ + public void printPricesStream(String product) { + long start = System.nanoTime(); + CompletableFuture[] futures = findPricesStream(product) + .map(f -> f.thenAccept(s -> System.out.println(s + " (done in " + ((System.nanoTime() - start) / 1_000_000) + " msecs)"))) + .toArray(CompletableFuture[]::new); + CompletableFuture.allOf(futures).join(); + System.out.println("All shops have now responded in " + ((System.nanoTime() - start) / 1_000_000) + " msecs"); + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/BestPriceFinderMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/BestPriceFinderMain.java new file mode 100644 index 0000000..a0994e0 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/BestPriceFinderMain.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java8.effective.async; + +import java.util.List; +import java.util.function.Supplier; + +/** + * 测试每种实现方案的执行时间 + */ +public class BestPriceFinderMain { + + private static BestPriceFinder bestPriceFinder = new BestPriceFinder(); + + public static void main(String[] args) { + execute("sequential", () -> bestPriceFinder.findPricesSequential("myPhone27S")); + execute("parallel", () -> bestPriceFinder.findPricesParallel("myPhone27S")); + execute("composed CompletableFuture", () -> bestPriceFinder.findPricesFuture("myPhone27S")); + bestPriceFinder.printPricesStream("myPhone27S"); + } + + private static void execute(String msg, Supplier> s) { + long start = System.nanoTime(); + System.out.println(s.get()); + long duration = (System.nanoTime() - start) / 1_000_000; + System.out.println(msg + " done in " + duration + " msecs"); + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/Discount.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/Discount.java new file mode 100644 index 0000000..992012c --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/Discount.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java8.effective.async; + +import static com.brianway.learning.java8.effective.async.Util.delay; +import static com.brianway.learning.java8.effective.async.Util.format; + +/** + * 折扣类 + */ +public class Discount { + + public enum Code { + NONE(0), + SILVER(5), + GOLD(10), + PLATINUM(15), + DIAMOND(20); + + private final int percentage; + + Code(int percentage) { + this.percentage = percentage; + } + } + + public static String applyDiscount(Quote quote) { + return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(), quote.getDiscountCode()); + } + + private static double apply(double price, Code code) { + delay(); + return format(price * (100 - code.percentage) / 100); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/ExchangeService.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/ExchangeService.java new file mode 100644 index 0000000..5b3ef55 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/ExchangeService.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java8.effective.async; + +import static com.brianway.learning.java8.effective.async.Util.delay; + +/** + * 货币兑换类 + */ +public class ExchangeService { + + public enum Money { + USD(1.0), + EUR(1.35387), + GBP(1.69715), + CAD(.92106), + MXN(.07683); + + private final double rate; + + Money(double rate) { + this.rate = rate; + } + } + + public static double getRate(Money source, Money destination) { + return getRateWithDelay(source, destination); + } + + private static double getRateWithDelay(Money source, Money destination) { + delay(); + return destination.rate / source.rate; + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/Quote.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/Quote.java new file mode 100644 index 0000000..0550251 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/Quote.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java8.effective.async; + +/** + * 解析商店返回的字符串 + */ +public class Quote { + + private final String shopName; + private final double price; + private final Discount.Code discountCode; + + public Quote(String shopName, double price, Discount.Code discountCode) { + this.shopName = shopName; + this.price = price; + this.discountCode = discountCode; + } + + public static Quote parse(String s) { + String[] split = s.split(":"); + String shopName = split[0]; + double price = Double.parseDouble(split[1]); + Discount.Code discountCode = Discount.Code.valueOf(split[2]); + return new Quote(shopName, price, discountCode); + } + + public String getShopName() { + return shopName; + } + + public double getPrice() { + return price; + } + + public Discount.Code getDiscountCode() { + return discountCode; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/Shop.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/Shop.java new file mode 100644 index 0000000..788226d --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/Shop.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java8.effective.async; + +import static com.brianway.learning.java8.effective.async.Util.delay; +import static com.brianway.learning.java8.effective.async.Util.format; + +import java.util.Random; + +/** + * 商店类 + * 报价按照 `name:price:code` 的格式 + */ +public class Shop { + + private final String name; + private final Random random; + + public Shop(String name) { + this.name = name; + random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); + } + + public String getPrice(String product) { + double price = calculatePrice(product); + Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)]; + return name + ":" + price + ":" + code; + } + + public double calculatePrice(String product) { + delay(); + return format(random.nextDouble() * product.charAt(0) + product.charAt(1)); + } + + public String getName() { + return name; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/Util.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/Util.java new file mode 100644 index 0000000..fcd6db2 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/Util.java @@ -0,0 +1,46 @@ +package com.brianway.learning.java8.effective.async; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.List; +import java.util.Locale; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +public class Util { + + private static final Random RANDOM = new Random(0); + private static final DecimalFormat formatter = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US)); + + public static void delay() { + int delay = 1000; + //int delay = 500 + RANDOM.nextInt(2000); + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public static double format(double number) { + synchronized (formatter) { + return new Double(formatter.format(number)); + } + } + + public static CompletableFuture> sequence(List> futures) { +/* + CompletableFuture allDoneFuture = + CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])); + return allDoneFuture.thenApply(v -> + futures.stream(). + map(future -> future.join()). + collect(Collectors.toList()) + ); +*/ + return CompletableFuture.supplyAsync(() -> futures.stream(). + map(CompletableFuture::join). + collect(Collectors.toList())); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/BestPriceFinder.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/BestPriceFinder.java new file mode 100644 index 0000000..092c439 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/BestPriceFinder.java @@ -0,0 +1,166 @@ +package com.brianway.learning.java8.effective.async.v1; + +import com.brianway.learning.java8.effective.async.ExchangeService; +import com.brianway.learning.java8.effective.async.ExchangeService.Money; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 通过不同的方案实现价格查询:顺序流,并行流,CompletableFuture + */ +public class BestPriceFinder { + + private final List shops = Arrays.asList(new Shop("BestPrice"), + new Shop("LetsSaveBig"), + new Shop("MyFavoriteShop"), + new Shop("BuyItAll") + //,new Shop("ShopEasy") + ); + + private final Executor executor = Executors.newFixedThreadPool( + shops.size(), + r -> { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + + }); + + public List findPricesSequential(String product) { + return shops.stream() + .map(shop -> shop.getName() + " price is " + shop.getPrice(product)) + .collect(Collectors.toList()); + } + + public List findPricesParallel(String product) { + return shops.parallelStream() + .map(shop -> shop.getName() + " price is " + shop.getPrice(product)) + .collect(Collectors.toList()); + } + + public List findPricesFuture(String product) { + List> priceFutures = + shops.stream() + .map(shop -> CompletableFuture.supplyAsync(() -> shop.getName() + " price is " + + shop.getPrice(product), executor)) + .collect(Collectors.toList()); + + List prices = priceFutures.stream() + .map(CompletableFuture::join) + .collect(Collectors.toList()); + return prices; + } + + //-------------------涉及汇率转换-------------------- + public List findPricesInUSDJava7(String product) { + ExecutorService executor = Executors.newCachedThreadPool(); + List> priceFutures = new ArrayList<>(); + for (Shop shop : shops) { + final Future futureRate = executor.submit(new Callable() { + public Double call() { + return ExchangeService.getRate(Money.EUR, ExchangeService.Money.USD); + } + }); + Future futurePriceInUSD = executor.submit(new Callable() { + public Double call() { + try { + double priceInEUR = shop.getPrice(product); + return priceInEUR * futureRate.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + }); + priceFutures.add(futurePriceInUSD); + } + List prices = new ArrayList<>(); + for (Future priceFuture : priceFutures) { + try { + prices.add(/*shop.getName() +*/ " price is " + priceFuture.get()); + } catch (ExecutionException | InterruptedException e) { + e.printStackTrace(); + } + } + return prices; + } + + public List findPricesInUSD(String product) { + List> priceFutures = new ArrayList<>(); + for (Shop shop : shops) { + // Start of Listing 10.20. + // Only the type of futurePriceInUSD has been changed to + // CompletableFuture so that it is compatible with the + // CompletableFuture::join operation below. + CompletableFuture futurePriceInUSD = + CompletableFuture.supplyAsync(() -> shop.getPrice(product)) + .thenCombine( + CompletableFuture.supplyAsync( + () -> ExchangeService.getRate(ExchangeService.Money.EUR, Money.USD)), + (price, rate) -> price * rate + ); + priceFutures.add(futurePriceInUSD); + } + // Drawback: The shop is not accessible anymore outside the loop, + // so the getName() call below has been commented out. + List prices = priceFutures + .stream() + .map(CompletableFuture::join) + .map(price -> /*shop.getName() +*/ " price is " + price) + .collect(Collectors.toList()); + return prices; + } + + public List findPricesInUSD2(String product) { + List> priceFutures = new ArrayList<>(); + for (Shop shop : shops) { + // Here, an extra operation has been added so that the shop name + // is retrieved within the loop. As a result, we now deal with + // CompletableFuture instances. + CompletableFuture futurePriceInUSD = + CompletableFuture.supplyAsync(() -> shop.getPrice(product)) + .thenCombine( + CompletableFuture.supplyAsync( + () -> ExchangeService.getRate(Money.EUR, Money.USD)), + (price, rate) -> price * rate + ).thenApply(price -> shop.getName() + " price is " + price); + priceFutures.add(futurePriceInUSD); + } + List prices = priceFutures + .stream() + .map(CompletableFuture::join) + .collect(Collectors.toList()); + return prices; + } + + public List findPricesInUSD3(String product) { + // Here, the for loop has been replaced by a mapping function... + Stream> priceFuturesStream = shops + .stream() + .map(shop -> CompletableFuture + .supplyAsync(() -> shop.getPrice(product)) + .thenCombine( + CompletableFuture.supplyAsync(() -> ExchangeService.getRate(Money.EUR, Money.USD)), + (price, rate) -> price * rate) + .thenApply(price -> shop.getName() + " price is " + price)); + // However, we should gather the CompletableFutures into a List so that the asynchronous + // operations are triggered before being "joined." + List> priceFutures = priceFuturesStream.collect(Collectors.toList()); + List prices = priceFutures + .stream() + .map(CompletableFuture::join) + .collect(Collectors.toList()); + return prices; + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/BestPriceFinderMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/BestPriceFinderMain.java new file mode 100644 index 0000000..2c463b0 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/BestPriceFinderMain.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java8.effective.async.v1; + +import java.util.List; +import java.util.function.Supplier; + +/** + * 测试每种实现方案的执行时间 + */ +public class BestPriceFinderMain { + + private static BestPriceFinder bestPriceFinder = new BestPriceFinder(); + + public static void main(String[] args) { + execute("sequential", () -> bestPriceFinder.findPricesSequential("myPhone27S")); + execute("parallel", () -> bestPriceFinder.findPricesParallel("myPhone27S")); + execute("composed CompletableFuture", () -> bestPriceFinder.findPricesFuture("myPhone27S")); + execute("combined USD CompletableFuture", () -> bestPriceFinder.findPricesInUSD("myPhone27S")); + execute("combined USD CompletableFuture v2", () -> bestPriceFinder.findPricesInUSD2("myPhone27S")); + execute("combined USD CompletableFuture v3", () -> bestPriceFinder.findPricesInUSD3("myPhone27S")); + } + + private static void execute(String msg, Supplier> s) { + long start = System.nanoTime(); + System.out.println(s.get()); + long duration = (System.nanoTime() - start) / 1_000_000; + System.out.println(msg + " done in " + duration + " msecs"); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/Shop.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/Shop.java new file mode 100644 index 0000000..5710f4d --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/Shop.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java8.effective.async.v1; + +import static com.brianway.learning.java8.effective.async.Util.delay; + +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +/** + * 商店类,第一版 + */ +public class Shop { + + private final String name; + private final Random random; + + public Shop(String name) { + this.name = name; + random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); + } + + public double getPrice(String product) { + return calculatePrice(product); + } + + /** + * 根据商品名随机生成价格 + */ + private double calculatePrice(String product) { + delay(); + return random.nextDouble() * product.charAt(0) + product.charAt(1); + } + + public Future getPriceAsync(String product) { + CompletableFuture futurePrice = new CompletableFuture<>(); + new Thread(() -> { + double price = calculatePrice(product); + futurePrice.complete(price); + }).start(); + return futurePrice; + } + + public String getName() { + return name; + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/ShopMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/ShopMain.java new file mode 100644 index 0000000..19e4764 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/async/v1/ShopMain.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java8.effective.async.v1; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * 使用异步 API + */ +public class ShopMain { + + public static void main(String[] args) { + Shop shop = new Shop("BestShop"); + long start = System.nanoTime(); + Future futurePrice = shop.getPriceAsync("my favorite product"); + long invocationTime = ((System.nanoTime() - start) / 1_000_000); + System.out.println("Invocation returned after " + invocationTime + + " msecs"); + // Do some more tasks, like querying other shops + doSomethingElse(); + // while the price of the product is being calculated + try { + double price = futurePrice.get(); + System.out.printf("Price is %.2f%n", price); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } + long retrievalTime = ((System.nanoTime() - start) / 1_000_000); + System.out.println("Price returned after " + retrievalTime + " msecs"); + } + + private static void doSomethingElse() { + System.out.println("Doing something else..."); + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/optional/Car.java b/java8/src/main/java/com/brianway/learning/java8/effective/optional/Car.java new file mode 100644 index 0000000..82384f4 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/optional/Car.java @@ -0,0 +1,12 @@ +package com.brianway.learning.java8.effective.optional; + +import java.util.Optional; + +public class Car { + + private Optional insurance; + + public Optional getInsurance() { + return insurance; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/optional/Insurance.java b/java8/src/main/java/com/brianway/learning/java8/effective/optional/Insurance.java new file mode 100644 index 0000000..11e4acb --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/optional/Insurance.java @@ -0,0 +1,10 @@ +package com.brianway.learning.java8.effective.optional; + +public class Insurance { + + private String name; + + public String getName() { + return name; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/optional/OptionalInAction.java b/java8/src/main/java/com/brianway/learning/java8/effective/optional/OptionalInAction.java new file mode 100644 index 0000000..55e0d83 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/optional/OptionalInAction.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java8.effective.optional; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * Created by brian on 17/3/27. + * 使用 Optional 实战示例 + */ +public class OptionalInAction { + + private static Map map = new HashMap<>(); + + public static void main(String[] args) { + Optional value = getValue("key"); + System.out.println(value.orElse("this is null")); + + System.out.println(stringToInt("123")); + System.out.println(stringToInt("dd")); + + } + + /** + * 用 Optional 封装可能为 null 的值 + */ + public static Optional getValue(String key) { + Optional value = Optional.ofNullable(map.get(key)); + return value; + } + + /** + * 异常与 Optional 的对比 + */ + public static Optional stringToInt(String s) { + try { + return Optional.of(Integer.parseInt(s)); + } catch (NumberFormatException e) { + return Optional.empty(); + } + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/optional/OptionalMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/optional/OptionalMain.java new file mode 100644 index 0000000..11546d1 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/optional/OptionalMain.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java8.effective.optional; + +import java.util.Optional; + +/** + * Optional 用法: + * - 使用 map 从 Optional 对象提取和转换值 + * - 使用 flatMap 链接 Optional 对象 + * - 两个 Optional 对象的组合 + * - 使用 filter 剔除特定值 + */ +public class OptionalMain { + + public static void main(String[] args) { + Optional person = Optional.of(new Person()); + //Optional person2 = Optional.empty(); + String name = getCarInsuranceName(person); + System.out.println(name); + } + + public static String getCarInsuranceName(Optional person) { + return person.flatMap(Person::getCar) + .flatMap(Car::getInsurance) + .map(Insurance::getName) + .orElse("Unknown"); + } + + public Insurance findCheapestInsurance(Person person, Car car) { + //省略业务逻辑 + Insurance cheapestCompany = new Insurance(); + return cheapestCompany; + } + + public Optional nullSafeFindCheapestInsurance(Optional person, Optional car) { + return person.flatMap( + p -> car.map( + c -> findCheapestInsurance(p, c))); + } + + public void PrintIfWithName(String name) { + Optional optInsurance = Optional.of(new Insurance()); + optInsurance.filter(insurance -> name.equals(insurance.getName())) + .ifPresent(x -> System.out.println("ok")); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/optional/Person.java b/java8/src/main/java/com/brianway/learning/java8/effective/optional/Person.java new file mode 100644 index 0000000..8ffaef8 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/optional/Person.java @@ -0,0 +1,12 @@ +package com.brianway.learning.java8.effective.optional; + +import java.util.Optional; + +public class Person { + + private Car car; + + public Optional getCar() { + return Optional.ofNullable(car); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/optional/ReadPositiveIntParam.java b/java8/src/main/java/com/brianway/learning/java8/effective/optional/ReadPositiveIntParam.java new file mode 100644 index 0000000..b6fa89a --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/optional/ReadPositiveIntParam.java @@ -0,0 +1,44 @@ +package com.brianway.learning.java8.effective.optional; + +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static java.util.Optional.ofNullable; + +import java.util.Optional; +import java.util.Properties; + +/** + * 使用 Optional 示例 + * test case 见 test 目录 + */ +public class ReadPositiveIntParam { + + public static int readDurationImperative(Properties props, String name) { + String value = props.getProperty(name); + if (value != null) { + try { + int i = Integer.parseInt(value); + if (i > 0) { + return i; + } + } catch (NumberFormatException nfe) { + } + } + return 0; + } + + public static int readDurationWithOptional(Properties props, String name) { + return ofNullable(props.getProperty(name)) + .flatMap(ReadPositiveIntParam::s2i) + .filter(i -> i > 0).orElse(0); + } + + public static Optional s2i(String s) { + try { + return of(Integer.parseInt(s)); + } catch (NumberFormatException e) { + return empty(); + } + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/ChainOfResponsibilityMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/ChainOfResponsibilityMain.java new file mode 100644 index 0000000..57232f1 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/ChainOfResponsibilityMain.java @@ -0,0 +1,62 @@ +package com.brianway.learning.java8.effective.tech; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +/** + * 责任链模式 + */ +public class ChainOfResponsibilityMain { + + public static void main(String[] args) { + //old school + ProcessingObject p1 = new HeaderTextProcessing(); + ProcessingObject p2 = new SpellCheckerProcessing(); + p1.setSuccessor(p2); + String result1 = p1.handle("Aren't labdas really sexy?!!"); + System.out.println(result1); + + // with lambdas + UnaryOperator headerProcessing = + (String text) -> "From Raoul, Mario and Alan: " + text; + UnaryOperator spellCheckerProcessing = + (String text) -> text.replaceAll("labda", "lambda"); + Function pipeline = headerProcessing.andThen(spellCheckerProcessing); + String result2 = pipeline.apply("Aren't labdas really sexy?!!"); + System.out.println(result2); + } + + static private abstract class ProcessingObject { + protected ProcessingObject successor; + + public void setSuccessor(ProcessingObject successor) { + this.successor = successor; + } + + public T handle(T input) { + T r = handleWork(input); + if (successor != null) { + return successor.handle(r); + } + return r; + } + + abstract protected T handleWork(T input); + } + + static private class HeaderTextProcessing + extends ProcessingObject { + public String handleWork(String text) { + return "From Raoul, Mario and Alan: " + text; + } + } + + static private class SpellCheckerProcessing + extends ProcessingObject { + public String handleWork(String text) { + return text.replaceAll("labda", "lambda"); + } + } +} + + diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/Debugging.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/Debugging.java new file mode 100644 index 0000000..31b9507 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/Debugging.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java8.effective.tech; + +import java.util.Arrays; +import java.util.List; + +/** + * 查看栈跟踪 + */ +public class Debugging { + public static void main(String[] args) { +// Arrays.asList(1, 2, 3).stream() +// .map(Debugging::divideByZero) +// .forEach(System.out::println); + + List points = Arrays.asList(new Point(12, 2), null); + //points.stream().map(p -> p.getX()).forEach(System.out::println); + points.stream().map(Point::getX).forEach(System.out::println); + } + + private static class Point { + private int x; + private int y; + + private Point(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + } + + public static int divideByZero(int n) { + return n / 0; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/FactoryMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/FactoryMain.java new file mode 100644 index 0000000..f234f17 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/FactoryMain.java @@ -0,0 +1,68 @@ +package com.brianway.learning.java8.effective.tech; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +/** + * 工厂模式 + */ +public class FactoryMain { + + public static void main(String[] args) { + Product p1 = ProductFactory.createProduct("loan"); + p1.printClassName(); + + // with lambdas + Supplier loanSupplier = Loan::new; + Product p2 = loanSupplier.get(); + p2.printClassName(); + + Product p3 = ProductFactory.createProductLambda("loan"); + p3.printClassName(); + } + + static private class ProductFactory { + public static Product createProduct(String name) { + switch (name) { + case "loan": + return new Loan(); + case "stock": + return new Stock(); + case "bond": + return new Bond(); + default: + throw new RuntimeException("No such product " + name); + } + } + + public static Product createProductLambda(String name) { + Supplier p = map.get(name); + if (p != null) return p.get(); + throw new RuntimeException("No such product " + name); + } + } + + private interface Product { + default void printClassName() { + System.out.println(getClass().getSimpleName()); + } + } + + static private class Loan implements Product { + } + + static private class Stock implements Product { + } + + static private class Bond implements Product { + } + + final static private Map> map = new HashMap<>(); + + static { + map.put("loan", Loan::new); + map.put("stock", Stock::new); + map.put("bond", Bond::new); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/ObserverMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/ObserverMain.java new file mode 100644 index 0000000..7f1c785 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/ObserverMain.java @@ -0,0 +1,86 @@ +package com.brianway.learning.java8.effective.tech; + +import java.util.ArrayList; +import java.util.List; + +/** + * 观察者模式 + */ +public class ObserverMain { + + public static void main(String[] args) { + //old school + Subject f = new Feed(); + f.registerObserver(new NYTimes()); + f.registerObserver(new Guardian()); + f.registerObserver(new LeMonde()); + f.notifyObservers("The queen said her favourite book is Java 8 in Action!"); + + // with lambdas + Feed feedLambda = new Feed(); + + feedLambda.registerObserver((String tweet) -> { + if (tweet != null && tweet.contains("money")) { + System.out.println("Breaking news in NY! " + tweet); + } + }); + feedLambda.registerObserver((String tweet) -> { + if (tweet != null && tweet.contains("queen")) { + System.out.println("Yet another news in London... " + tweet); + } + }); + + feedLambda.notifyObservers("Money money money, give me money!"); + + } + + interface Observer { + void inform(String tweet); + } + + interface Subject { + void registerObserver(Observer o); + + void notifyObservers(String tweet); + } + + static private class NYTimes implements Observer { + @Override + public void inform(String tweet) { + if (tweet != null && tweet.contains("money")) { + System.out.println("Breaking news in NY!" + tweet); + } + } + } + + static private class Guardian implements Observer { + @Override + public void inform(String tweet) { + if (tweet != null && tweet.contains("queen")) { + System.out.println("Yet another news in London... " + tweet); + } + } + } + + static private class LeMonde implements Observer { + @Override + public void inform(String tweet) { + if (tweet != null && tweet.contains("wine")) { + System.out.println("Today cheese, wine and news! " + tweet); + } + } + } + + static private class Feed implements Subject { + private final List observers = new ArrayList<>(); + + public void registerObserver(Observer o) { + this.observers.add(o); + } + + public void notifyObservers(String tweet) { + observers.forEach(o -> o.inform(tweet)); + } + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/Peek.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/Peek.java new file mode 100644 index 0000000..2ccf379 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/Peek.java @@ -0,0 +1,25 @@ +package com.brianway.learning.java8.effective.tech; + +import static java.util.stream.Collectors.toList; + +import java.util.List; +import java.util.stream.Stream; + +/** + * 使用日志调试 + */ +public class Peek { + + public static void main(String[] args) { + + List result = Stream.of(2, 3, 4, 5) + .peek(x -> System.out.println("taking from stream: " + x)) + .map(x -> x + 17) + .peek(x -> System.out.println("after map: " + x)) + .filter(x -> x % 2 == 0) + .peek(x -> System.out.println("after filter: " + x)) + .limit(3) + .peek(x -> System.out.println("after limit: " + x)) + .collect(toList()); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/StrategyMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/StrategyMain.java new file mode 100644 index 0000000..1cf6e5d --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/StrategyMain.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java8.effective.tech; + +/** + * 策略模式 + */ +public class StrategyMain { + + public static void main(String[] args) { + // old school + Validator v1 = new Validator(new IsNumeric()); + System.out.println(v1.validate("aaaa")); + Validator v2 = new Validator(new IsAllLowerCase()); + System.out.println(v2.validate("bbbb")); + + // with lambdas + Validator v3 = new Validator((String s) -> s.matches("\\d+")); + System.out.println(v3.validate("aaaa")); + Validator v4 = new Validator((String s) -> s.matches("[a-z]+")); + System.out.println(v4.validate("bbbb")); + } + + interface ValidationStrategy { + boolean execute(String s); + } + + static private class IsAllLowerCase implements ValidationStrategy { + public boolean execute(String s) { + return s.matches("[a-z]+"); + } + } + + static private class IsNumeric implements ValidationStrategy { + public boolean execute(String s) { + return s.matches("\\d+"); + } + } + + static private class Validator { + private final ValidationStrategy strategy; + + public Validator(ValidationStrategy v) { + this.strategy = v; + } + + public boolean validate(String s) { + return strategy.execute(s); + } + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/tech/TemplateMain.java b/java8/src/main/java/com/brianway/learning/java8/effective/tech/TemplateMain.java new file mode 100644 index 0000000..b7e67f9 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/tech/TemplateMain.java @@ -0,0 +1,60 @@ +package com.brianway.learning.java8.effective.tech; + +import java.util.function.Consumer; + +/** + * Created by brian on 17/3/24. + * 模版方法 + */ +public class TemplateMain { + + public static void main(String[] args) { + // old school + new OnlineBanking() { + @Override + void makeCustomerHappy(Customer c) { + System.out.println("Hello " + c.getName()); + } + }.processCustomer(1); + + // with lambdas + new OnlineBankingLambda() + .processCustomer(1, (Customer c) -> System.out.println("Hello " + c.getName())); + + } + + private static abstract class OnlineBanking { + void processCustomer(int id) { + Customer c = Database.getCustomerWithId(id); + makeCustomerHappy(c); + } + + abstract void makeCustomerHappy(Customer c); + + } + + private static class OnlineBankingLambda { + void processCustomer(int id, Consumer makeCustomerHappy) { + Customer c = Database.getCustomerWithId(id); + makeCustomerHappy.accept(c); + } + } + + // dummy Customer class + static private class Customer { + private int id = 1; + private String name = "Brian"; + + private String getName() { + return name; + } + } + + // dummy Datbase class + static private class Database { + static Customer getCustomerWithId(int id) { + return new Customer(); + } + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/effective/time/DateTimeExamples.java b/java8/src/main/java/com/brianway/learning/java8/effective/time/DateTimeExamples.java new file mode 100644 index 0000000..e3b63f0 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/effective/time/DateTimeExamples.java @@ -0,0 +1,162 @@ +package com.brianway.learning.java8.effective.time; + +import static java.time.temporal.TemporalAdjusters.lastDayOfMonth; +import static java.time.temporal.TemporalAdjusters.nextOrSame; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.DayOfWeek; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.time.chrono.JapaneseDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAdjuster; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +/** + * 新的时间和日期 API 示例 + */ +public class DateTimeExamples { + + private static final ThreadLocal formatters = new ThreadLocal() { + protected DateFormat initialValue() { + return new SimpleDateFormat("dd-MMM-yyyy"); + } + }; + + public static void main(String[] args) { + System.out.println("---------------useOldDate---------------------"); + useOldDate(); + System.out.println("---------------useLocalDate-----------------"); + useLocalDate(); + System.out.println("-------------useTemporalAdjuster---------------"); + useTemporalAdjuster(); + System.out.println("--------------useDateFormatter---------------"); + useDateFormatter(); + } + + private static void useOldDate() { + Date date = new Date(114, 2, 18); + System.out.println(date); + + System.out.println(formatters.get().format(date)); + + Calendar calendar = Calendar.getInstance(); + calendar.set(2014, Calendar.FEBRUARY, 18); + System.out.println(calendar); + } + + private static void useLocalDate() { + LocalDate date = LocalDate.of(2014, 3, 18); + int year = date.getYear(); // 2014 + Month month = date.getMonth(); // MARCH + int day = date.getDayOfMonth(); // 18 + DayOfWeek dow = date.getDayOfWeek(); // TUESDAY + int len = date.lengthOfMonth(); // 31 (days in March) + boolean leap = date.isLeapYear(); // false (not a leap year) + System.out.println(date); + + int y = date.get(ChronoField.YEAR); + int m = date.get(ChronoField.MONTH_OF_YEAR); + int d = date.get(ChronoField.DAY_OF_MONTH); + + LocalTime time = LocalTime.of(13, 45, 20); // 13:45:20 + int hour = time.getHour(); // 13 + int minute = time.getMinute(); // 45 + int second = time.getSecond(); // 20 + System.out.println(time); + + LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); // 2014-03-18T13:45 + LocalDateTime dt2 = LocalDateTime.of(date, time); + LocalDateTime dt3 = date.atTime(13, 45, 20); + LocalDateTime dt4 = date.atTime(time); + LocalDateTime dt5 = time.atDate(date); + System.out.println(dt1); + + LocalDate date1 = dt1.toLocalDate(); + System.out.println(date1); + LocalTime time1 = dt1.toLocalTime(); + System.out.println(time1); + + Instant instant = Instant.ofEpochSecond(44 * 365 * 86400); + Instant now = Instant.now(); + + Duration d1 = Duration.between(LocalTime.of(13, 45, 10), time); + Duration d2 = Duration.between(instant, now); + System.out.println(d1.getSeconds()); + System.out.println(d2.getSeconds()); + + Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES); + System.out.println(threeMinutes); + + JapaneseDate japaneseDate = JapaneseDate.from(date); + System.out.println(japaneseDate); + } + + private static void useTemporalAdjuster() { + LocalDate date = LocalDate.of(2014, 3, 18); + date = date.with(nextOrSame(DayOfWeek.SUNDAY)); + System.out.println(date); + date = date.with(lastDayOfMonth()); + System.out.println(date); + + date = date.with(new NextWorkingDay()); + System.out.println(date); + date = date.with(nextOrSame(DayOfWeek.FRIDAY)); + System.out.println(date); + date = date.with(new NextWorkingDay()); + System.out.println(date); + + date = date.with(nextOrSame(DayOfWeek.FRIDAY)); + System.out.println(date); + date = date.with(DateTimeExamples::nextWorkingDay); + System.out.println(date); + } + + private static class NextWorkingDay implements TemporalAdjuster { + @Override + public Temporal adjustInto(Temporal temporal) { + return nextWorkingDay(temporal); + } + } + + private static Temporal nextWorkingDay(Temporal temporal) { + DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK)); + int dayToAdd = 1; + if (dow == DayOfWeek.FRIDAY) dayToAdd = 3; + if (dow == DayOfWeek.SATURDAY) dayToAdd = 2; + return temporal.plus(dayToAdd, ChronoUnit.DAYS); + } + + private static void useDateFormatter() { + LocalDate date = LocalDate.of(2014, 3, 18); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN); + + System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); + System.out.println(date.format(formatter)); + System.out.println(date.format(italianFormatter)); + + DateTimeFormatter complexFormatter = new DateTimeFormatterBuilder() + .appendText(ChronoField.DAY_OF_MONTH) + .appendLiteral(". ") + .appendText(ChronoField.MONTH_OF_YEAR) + .appendLiteral(" ") + .appendText(ChronoField.YEAR) + .parseCaseInsensitive() + .toFormatter(Locale.ITALIAN); + + System.out.println(date.format(complexFormatter)); + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/lambda/ConstructorReference.java b/java8/src/main/java/com/brianway/learning/java8/lambda/ConstructorReference.java new file mode 100644 index 0000000..cfcadbd --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/lambda/ConstructorReference.java @@ -0,0 +1,87 @@ +package com.brianway.learning.java8.lambda; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Created by brian on 17/2/28. + * 构造函数引用 + */ +public class ConstructorReference { + + public static void main(String[] args) { + //Apple()的构造函数 + Supplier c1 = Apple::new; + Apple a1 = c1.get(); + System.out.println(a1); + + //Apple(int weight)的构造函数 + Function c2 = Apple::new; + Apple a2 = c2.apply(110); + System.out.println(a2); + + List weights = Arrays.asList(7, 3, 4, 10); + List apples = map(weights, Apple::new); + System.out.println("list of weights:"); + apples.stream().forEach(System.out::println); + + //Apple(int weight, String color)的构造函数 + BiFunction c3 = Apple::new; + Apple a3 = c3.apply("green", 110); + System.out.println(a3); + } + + public static List map(List list, + Function f) { + List result = new ArrayList<>(); + //TODO + for (Integer e : list) { + result.add(f.apply(e)); + } + return result; + } + + public static class Apple { + private int weight = 0; + private String color = ""; + + public Apple() { + } + + public Apple(int weight) { + this.weight = weight; + } + + public Apple(String color, int weight) { + this.weight = weight; + this.color = color; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String toString() { + return "Apple{" + + "color='" + color + '\'' + + ", weight=" + weight + + '}'; + } + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/lambda/ExecuteAround.java b/java8/src/main/java/com/brianway/learning/java8/lambda/ExecuteAround.java new file mode 100644 index 0000000..9a0a608 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/lambda/ExecuteAround.java @@ -0,0 +1,54 @@ +package com.brianway.learning.java8.lambda; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +/** + * Lambda实践: 环绕执行模式 + * 1. 行为参数化 + * 2. 使用函数式接口来传递行为 + * 3. 执行一个行为 + * 4. 传递 Lambda + */ +public class ExecuteAround { + + private static final String RESOURCE_ROOT = ExecuteAround.class + .getResource("/").getPath() + "/data-lambda.txt"; + + public static void main(String... args) throws IOException { + + // method we want to refactor to make more flexible + String result = processFileLimited(); + System.out.println(result); + + System.out.println("---"); + + String oneLine = processFile(BufferedReader::readLine); + System.out.println(oneLine); + + String twoLines = processFile((BufferedReader b) -> b.readLine() + b.readLine()); + System.out.println(twoLines); + + } + + public static String processFileLimited() throws IOException { + try (BufferedReader br = + new BufferedReader(new FileReader(RESOURCE_ROOT))) { + return br.readLine(); + } + } + + public static String processFile(BufferedReaderProcessor p) throws IOException { + try (BufferedReader br = new BufferedReader(new FileReader(RESOURCE_ROOT))) { + return p.process(br); + } + + } + + @FunctionalInterface + public interface BufferedReaderProcessor { + String process(BufferedReader b) throws IOException; + + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java b/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java new file mode 100644 index 0000000..bb730ea --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/lambda/FilteringApples.java @@ -0,0 +1,92 @@ +package com.brianway.learning.java8.lambda; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; + +/** + * Created by brian on 16/12/26. + * + * 传递代码的例子 + * 分别使用了方法引用和Lambda(匿名函数) + */ +public class FilteringApples { + public static void main(String[] args) { + List inventory = Arrays.asList(new Apple(80, "green"), + new Apple(155, "green"), + new Apple(120, "red")); + + List greenApples = filter(inventory, FilteringApples::isGreenApple); + System.out.println(greenApples); + + List greenApples2 = filter(inventory, (Apple a) -> "green".equals(a.getColor())); + System.out.println(greenApples2); + + List heavyApples = filter(inventory, FilteringApples::isHeavyApple); + System.out.println(heavyApples); + + List heavyApples2 = filter(inventory, (Apple a) -> a.getWeight() > 150); + System.out.println(heavyApples2); + + } + + /** + * 根据抽象条件筛选 + * 将迭代集合的逻辑和要应用到集合中每个元素的行为区分开 + * + * @param inventory + * @param p + * @return + */ + public static List filter(List inventory, Predicate p) { + List result = new ArrayList<>(); + for (Apple apple : inventory) { + if (p.test(apple)) { + result.add(apple); + } + } + return result; + } + + public static boolean isGreenApple(Apple apple) { + return "green".equals(apple.getColor()); + } + + public static boolean isHeavyApple(Apple apple) { + return apple.getWeight() > 150; + } + + public static class Apple { + private int weight = 0; + private String color = ""; + + public Apple(int weight, String color) { + this.weight = weight; + this.color = color; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String toString() { + return "Apple{" + + "color='" + color + '\'' + + ", weight=" + weight + + '}'; + } + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/lambda/FunctionDescriptor.java b/java8/src/main/java/com/brianway/learning/java8/lambda/FunctionDescriptor.java new file mode 100644 index 0000000..d122151 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/lambda/FunctionDescriptor.java @@ -0,0 +1,69 @@ +package com.brianway.learning.java8.lambda; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * Created by brian on 17/2/27. + * Java 8 中常用函数式接口 + */ +public class FunctionDescriptor { + + public static void main(String[] args) { + //使用 Predicate + Predicate nonEmptyStringPredicate = (String s) -> !s.isEmpty(); + List listOfStrings = Arrays.asList("aaa", "ss", ""); + List nonEmpty = filter(listOfStrings, nonEmptyStringPredicate); + System.out.println("nonEmpty.size() == 2 " + (nonEmpty.size() == 2)); + + //使用 Consumer + forEach(Arrays.asList(1, 2, 3, 4, 5), System.out::println); + + //使用 Function + List lengthsOfWord = map( + Arrays.asList("lambda", "in", "action"), + String::length + ); + forEach(lengthsOfWord, System.out::println); + } + + /** + * 使用 Predicate + */ + public static List filter(List list, Predicate p) { + List results = new ArrayList<>(); + //TODO + for (T s : list) { + if (p.test(s)) { + results.add(s); + } + } + return results; + } + + /** + * 使用 Consumer + */ + public static void forEach(List list, Consumer c) { + //TODO + for (T i : list) { + c.accept(i); + } + } + + /** + * 使用 Function + */ + public static List map(List list, Function f) { + List result = new ArrayList<>(); + //TODO + for (T s : list) { + result.add(f.apply(s)); + } + return result; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java new file mode 100644 index 0000000..e98499d --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/BuildingStreams.java @@ -0,0 +1,93 @@ +package com.brianway.learning.java8.streamapi; + +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.function.IntSupplier; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * 构建流:从值序列,数组,文件来创建流 + * 斐波拉切数列的几种生成方法 + */ +public class BuildingStreams { + + public static void main(String... args) throws Exception { + + /** + * 由值创建流 + */ + // Stream.of + Stream stream = Stream.of("Java 8", "Lambdas", "In", "Action"); + stream.map(String::toUpperCase).forEach(System.out::println); + + // Stream.empty + Stream emptyStream = Stream.empty(); + + /** + * 由数组创建流 + */ + // Arrays.stream + int[] numbers = {2, 3, 5, 7, 11, 13}; + System.out.println(Arrays.stream(numbers).sum()); + + /** + * 由函数生成流:创建无限流 + */ + // Stream.iterate + Stream.iterate(0, n -> n + 2) + .limit(10) + .forEach(System.out::println); + + // fibonnaci with iterate + Stream.iterate(new int[] {0, 1}, t -> new int[] {t[1], t[0] + t[1]}) + .limit(10) + .forEach(t -> System.out.println("(" + t[0] + ", " + t[1] + ")")); + + Stream.iterate(new int[] {0, 1}, t -> new int[] {t[1], t[0] + t[1]}) + .limit(10) + .map(t -> t[0]) + .forEach(System.out::println); + + // random stream of doubles with Stream.generate + Stream.generate(Math::random) + .limit(10) + .forEach(System.out::println); + + // stream of 1s with Stream.generate + IntStream.generate(() -> 1) + .limit(5) + .forEach(System.out::println); + + IntStream.generate(() -> 2) + .limit(5) + .forEach(System.out::println); + + IntSupplier fib = new IntSupplier() { + private int previous = 0; + private int current = 1; + + public int getAsInt() { + int nextValue = this.previous + this.current; + this.previous = this.current; + this.current = nextValue; + return this.previous; + } + }; + IntStream.generate(fib).limit(10).forEach(System.out::println); + + /** + * 由文件生成流 + */ + String path = BuildingStreams.class.getResource("/").getPath() + "/data-building.txt"; + long uniqueWords = Files.lines(Paths.get(path), Charset.defaultCharset()) + .flatMap(line -> Arrays.stream(line.split(" "))) + .distinct() + .count(); + + System.out.println("There are " + uniqueWords + " unique words in data.txt"); + + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java new file mode 100644 index 0000000..64dc1a2 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Dish.java @@ -0,0 +1,63 @@ +package com.brianway.learning.java8.streamapi; + +import java.util.Arrays; +import java.util.List; + +/** + * 菜肴类 + */ +public class Dish { + + private final String name; + private final boolean vegetarian; + private final int calories; + private final Type type; + + public Dish(String name, boolean vegetarian, int calories, Type type) { + this.name = name; + this.vegetarian = vegetarian; + this.calories = calories; + this.type = type; + } + + public String getName() { + return name; + } + + public boolean isVegetarian() { + return vegetarian; + } + + public int getCalories() { + return calories; + } + + public Type getType() { + return type; + } + + public enum Type { + MEAT, + FISH, + OTHER + } + + @Override + public String toString() { + return name; + } + + /** + * 菜肴列表 + */ + public static final List menu = + Arrays.asList(new Dish("pork", false, 800, Dish.Type.MEAT), + new Dish("beef", false, 700, Dish.Type.MEAT), + new Dish("chicken", false, 400, Dish.Type.MEAT), + new Dish("french fries", true, 530, Dish.Type.OTHER), + new Dish("rice", true, 350, Dish.Type.OTHER), + new Dish("season fruit", true, 120, Dish.Type.OTHER), + new Dish("pizza", true, 550, Dish.Type.OTHER), + new Dish("prawns", false, 400, Dish.Type.FISH), + new Dish("salmon", false, 450, Dish.Type.FISH)); +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java new file mode 100644 index 0000000..fb0aac5 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/Laziness.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java8.streamapi; + +import static java.util.stream.Collectors.toList; + +import java.util.Arrays; +import java.util.List; + +/** + * 流操作-中间操作 + */ +public class Laziness { + + public static void main(String[] args) { + List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8); + List twoEvenSquares = + numbers.stream() + .filter(n -> { + System.out.println("filtering " + n); + return n % 2 == 0; + }) + .map(n -> { + System.out.println("mapping " + n); + return n * n; + }) + .limit(2) + .collect(toList()); + + twoEvenSquares.stream().forEach(System.out::println); + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java new file mode 100644 index 0000000..828434c --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamBasic.java @@ -0,0 +1,59 @@ +package com.brianway.learning.java8.streamapi; + +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * 指令式和函数式分别挑选低热量食物名 + */ +public class StreamBasic { + + public static void main(String... args) { + // Java 7 + getLowCaloricDishesNamesInJava7(Dish.menu).forEach(System.out::println); + + System.out.println("---"); + + // Java 8 + getLowCaloricDishesNamesInJava8(Dish.menu).forEach(System.out::println); + + } + + /** + * 指令式 + */ + public static List getLowCaloricDishesNamesInJava7(List dishes) { + List lowCaloricDishes = new ArrayList<>(); + for (Dish d : dishes) { + if (d.getCalories() < 400) { + lowCaloricDishes.add(d); + } + } + List lowCaloricDishesName = new ArrayList<>(); + Collections.sort(lowCaloricDishes, new Comparator() { + public int compare(Dish d1, Dish d2) { + return Integer.compare(d1.getCalories(), d2.getCalories()); + } + }); + for (Dish d : lowCaloricDishes) { + lowCaloricDishesName.add(d.getName()); + } + return lowCaloricDishesName; + } + + /** + * 函数式 + */ + public static List getLowCaloricDishesNamesInJava8(List dishes) { + return dishes.stream() + .filter(d -> d.getCalories() < 400) + .sorted(comparing(Dish::getCalories)) + .map(Dish::getName) + .collect(toList()); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamOperation.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamOperation.java new file mode 100644 index 0000000..19e3e77 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/StreamOperation.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java8.streamapi; + +import static com.brianway.learning.java8.streamapi.Dish.menu; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by brian on 17/2/28. + * 流操作:中间操作和终端操作 + * 流的延迟性质 + * 1. limit 操作,短路 + * 2. filter 和 map 操作, 循环合并 + */ +public class StreamOperation { + public static void main(String[] args) { + List names = menu.stream() + .filter(d -> { + System.out.println("filtering " + d.getName()); + return d.getCalories() > 300; + }) + .map(d -> { + System.out.println("mapping " + d.getName()); + return d.getName(); + }) + .limit(3) + .collect(Collectors.toList()); + System.out.println(names); + + //forEach 是一个返回 void 的终端操作 + System.out.println("------forEach-------"); + menu.stream().forEach(System.out::println); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/CollectorHarness.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/CollectorHarness.java new file mode 100644 index 0000000..af91a7c --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/CollectorHarness.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java8.streamapi.collect; + +import java.util.function.Consumer; + +/** + * 比较收集器的性能 + */ +public class CollectorHarness { + + public static void main(String[] args) { + System.out.println("Partitioning done in: " + execute(PartitionPrimeNumbers::partitionPrimes) + " msecs"); + System.out.println("Partitioning done in: " + execute(PartitionPrimeNumbers::partitionPrimesWithCustomCollector) + " msecs"); + } + + private static long execute(Consumer primePartitioner) { + long fastest = Long.MAX_VALUE; + for (int i = 0; i < 10; i++) { + long start = System.nanoTime(); + primePartitioner.accept(1_000_000); + long duration = (System.nanoTime() - start) / 1_000_000; + if (duration < fastest) fastest = duration; + System.out.println("done in " + duration); + } + return fastest; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Grouping.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Grouping.java new file mode 100644 index 0000000..608c2b1 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Grouping.java @@ -0,0 +1,110 @@ +package com.brianway.learning.java8.streamapi.collect; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.maxBy; +import static java.util.stream.Collectors.summingInt; +import static java.util.stream.Collectors.toSet; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +/** + * 分组 + */ +public class Grouping { + + private enum CaloricLevel { + DIET, + NORMAL, + FAT + } + + public static void main(String... args) { + System.out.println("Dishes grouped by type: " + groupDishesByType()); + System.out.println("Dishes grouped by caloric level: " + groupDishesByCaloricLevel()); + System.out.println("Dishes grouped by type and caloric level: " + groupDishedByTypeAndCaloricLevel()); + System.out.println("Count dishes in groups: " + countDishesInGroups()); + System.out.println("Most caloric dishes by type: " + mostCaloricDishesByType()); + System.out.println("Most caloric dishes by type: " + mostCaloricDishesByTypeWithoutOprionals()); + System.out.println("Sum calories by type: " + sumCaloriesByType()); + System.out.println("Caloric levels by type: " + caloricLevelsByType()); + } + + private static CaloricLevel getCaloricLevel(Dish dish) { + if (dish.getCalories() <= 400) { + return CaloricLevel.DIET; + } else if (dish.getCalories() <= 700) { + return CaloricLevel.NORMAL; + } else { + return CaloricLevel.FAT; + } + } + + private static Map> groupDishesByType() { + return menu.stream().collect(groupingBy(Dish::getType)); + } + + private static Map> groupDishesByCaloricLevel() { + return menu.stream().collect( + groupingBy(Grouping::getCaloricLevel)); + } + + /** + * 多级分组 + */ + private static Map>> groupDishedByTypeAndCaloricLevel() { + return menu.stream().collect( + groupingBy(Dish::getType, + groupingBy(Grouping::getCaloricLevel) + ) + ); + } + + /** + * 按子数组收集数据 + */ + private static Map countDishesInGroups() { + return menu.stream().collect(groupingBy(Dish::getType, counting())); + } + + private static Map> mostCaloricDishesByType() { + return menu.stream().collect( + groupingBy(Dish::getType, + maxBy(Comparator.comparingInt(Dish::getCalories))) + ); + } + + /** + * 按子数组收集数据,把收集器的结果转换为另一种类型 + */ + private static Map mostCaloricDishesByTypeWithoutOprionals() { + return menu.stream().collect( + groupingBy(Dish::getType, + collectingAndThen( + maxBy(Comparator.comparingInt(Dish::getCalories)), + Optional::get))); + } + + /** + * 与 groupingBy 联合使用的其他收集器例子 + */ + private static Map sumCaloriesByType() { + return menu.stream().collect(groupingBy(Dish::getType, + summingInt(Dish::getCalories))); + } + + private static Map> caloricLevelsByType() { + return menu.stream().collect( + groupingBy(Dish::getType, mapping( + Grouping::getCaloricLevel, + toSet()))); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/GroupingTransactions.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/GroupingTransactions.java new file mode 100644 index 0000000..47aad70 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/GroupingTransactions.java @@ -0,0 +1,87 @@ +package com.brianway.learning.java8.streamapi.collect; + +import static java.util.stream.Collectors.groupingBy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 分别使用指令式和函数式进行分组 + */ +public class GroupingTransactions { + + public static List transactions = Arrays.asList( + new Transaction(Currency.EUR, 1500.0), + new Transaction(Currency.USD, 2300.0), + new Transaction(Currency.GBP, 9900.0), + new Transaction(Currency.EUR, 1100.0), + new Transaction(Currency.JPY, 7800.0), + new Transaction(Currency.CHF, 6700.0), + new Transaction(Currency.EUR, 5600.0), + new Transaction(Currency.USD, 4500.0), + new Transaction(Currency.CHF, 3400.0), + new Transaction(Currency.GBP, 3200.0), + new Transaction(Currency.USD, 4600.0), + new Transaction(Currency.JPY, 5700.0), + new Transaction(Currency.EUR, 6800.0)); + + public static void main(String... args) { + groupImperatively(); + groupFunctionally(); + + } + + private static void groupImperatively() { + Map> transactionsByCurrencies = new HashMap<>(); + for (Transaction transaction : transactions) { + Currency currency = transaction.getCurrency(); + List transactionsForCurrency = transactionsByCurrencies.get(currency); + if (transactionsForCurrency == null) { + transactionsForCurrency = new ArrayList<>(); + transactionsByCurrencies.put(currency, transactionsForCurrency); + } + transactionsForCurrency.add(transaction); + } + + System.out.println(transactionsByCurrencies); + } + + private static void groupFunctionally() { + Map> transactionsByCurrencies = transactions.stream().collect(groupingBy(Transaction::getCurrency)); + System.out.println(transactionsByCurrencies); + } + + public static class Transaction { + private final Currency currency; + private final double value; + + public Transaction(Currency currency, double value) { + this.currency = currency; + this.value = value; + } + + public Currency getCurrency() { + return currency; + } + + public double getValue() { + return value; + } + + @Override + public String toString() { + return currency + " " + value; + } + } + + public enum Currency { + EUR, + USD, + JPY, + GBP, + CHF + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/PartitionPrimeNumbers.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/PartitionPrimeNumbers.java new file mode 100644 index 0000000..2a29b40 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/PartitionPrimeNumbers.java @@ -0,0 +1,145 @@ +package com.brianway.learning.java8.streamapi.collect; + +import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH; +import static java.util.stream.Collectors.partitioningBy; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * 得到 100 以内的质数和非质数 + * + * - 分区:分类的特殊情况。分区函数返回一个布尔值 + * - Collector + */ +public class PartitionPrimeNumbers { + + public static void main(String... args) { + System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimes(100)); + System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithCustomCollector(100)); + System.out.println("Numbers partitioned in prime and non-prime: " + partitionPrimesWithInlineCollector(100)); + + } + + public static Map> partitionPrimes(int n) { + return IntStream.rangeClosed(2, n).boxed() + .collect(partitioningBy(PartitionPrimeNumbers::isPrime)); + } + + /** + * 判断一个数是不是质数 + */ + public static boolean isPrime(int candidate) { + return IntStream.rangeClosed(2, candidate - 1) + .limit((long) Math.floor(Math.sqrt((double) candidate)) - 1) + .noneMatch(i -> candidate % i == 0); + } + + public static Map> partitionPrimesWithCustomCollector(int n) { + return IntStream.rangeClosed(2, n).boxed().collect(new PrimeNumbersCollector()); + } + + /** + * 仅用质数作除数 + * + * @param primes 部分结果 + * @param candidate 要判断的数 + * @return + */ + public static boolean isPrime(List primes, Integer candidate) { + double candidateRoot = Math.sqrt((double) candidate); + //return primes.stream().filter(p -> p < candidateRoot).noneMatch(p -> candidate % p == 0); + return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(i -> candidate % i == 0); + } + + /** + * 返回元素满足谓词的最长前缀 + */ + public static List takeWhile(List list, Predicate p) { + int i = 0; + for (A item : list) { + if (!p.test(item)) { + return list.subList(0, i); + } + i++; + } + return list; + } + + /** + * Collector + * 1.建立新的结果容器: supplier 方法 + * 2.将元素添到结果容器: accumulator 方法 + * 3.对容器应用最终转换: finisher 方法 + * 4.合并两个结果容器: combiner + * 5.characteristics 方法 + */ + public static class PrimeNumbersCollector + implements Collector>, Map>> { + + @Override + public Supplier>> supplier() { + return () -> new HashMap>() {{ + put(true, new ArrayList<>()); + put(false, new ArrayList<>()); + }}; + } + + @Override + public BiConsumer>, Integer> accumulator() { + return (Map> acc, Integer candidate) -> { + acc.get(isPrime(acc.get(true), candidate)) + .add(candidate); + }; + } + + @Override + public BinaryOperator>> combiner() { + return (Map> map1, Map> map2) -> { + map1.get(true).addAll(map2.get(true)); + map1.get(false).addAll(map2.get(false)); + return map1; + }; + } + + @Override + public Function>, Map>> finisher() { + return i -> i; + } + + @Override + public Set characteristics() { + return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH)); + } + } + + public static Map> partitionPrimesWithInlineCollector(int n) { + return Stream.iterate(2, i -> i + 1).limit(n) + .collect( + () -> new HashMap>() {{ + put(true, new ArrayList<>()); + put(false, new ArrayList<>()); + }}, + (acc, candidate) -> + acc.get(isPrime(acc.get(true), candidate)) + .add(candidate) + , + (map1, map2) -> { + map1.get(true).addAll(map2.get(true)); + map1.get(false).addAll(map2.get(false)); + }); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Partitioning.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Partitioning.java new file mode 100644 index 0000000..8810f88 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Partitioning.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java8.streamapi.collect; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.Comparator.comparingInt; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.maxBy; +import static java.util.stream.Collectors.partitioningBy; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * 分区 + */ +public class Partitioning { + + public static void main(String... args) { + System.out.println("Dishes partitioned by vegetarian: " + partitionByVegeterian()); + System.out.println("Vegetarian Dishes by type: " + vegetarianDishesByType()); + System.out.println("Most caloric dishes by vegetarian: " + mostCaloricPartitionedByVegetarian()); + } + + private static Map> partitionByVegeterian() { + return menu.stream().collect(partitioningBy(Dish::isVegetarian)); + } + + private static Map>> vegetarianDishesByType() { + return menu.stream().collect(partitioningBy(Dish::isVegetarian, groupingBy(Dish::getType))); + } + + private static Object mostCaloricPartitionedByVegetarian() { + return menu.stream().collect( + partitioningBy(Dish::isVegetarian, + collectingAndThen( + maxBy(comparingInt(Dish::getCalories)), + Optional::get))); + } +} + diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Reducing.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Reducing.java new file mode 100644 index 0000000..11f4bc8 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Reducing.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java8.streamapi.collect; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.stream.Collectors.reducing; + +/** + * 收集器的灵活性,以不同的方法执行相同的操作 + */ +public class Reducing { + + public static void main(String... args) { + System.out.println("Total calories in menu: " + calculateTotalCalories()); + System.out.println("Total calories in menu: " + calculateTotalCaloriesWithMethodReference()); + System.out.println("Total calories in menu: " + calculateTotalCaloriesWithoutCollectors()); + System.out.println("Total calories in menu: " + calculateTotalCaloriesUsingSum()); + } + + private static int calculateTotalCalories() { + return menu.stream().collect(reducing(0, Dish::getCalories, (Integer i, Integer j) -> i + j)); + } + + private static int calculateTotalCaloriesWithMethodReference() { + return menu.stream().collect(reducing(0, Dish::getCalories, Integer::sum)); + } + + private static int calculateTotalCaloriesWithoutCollectors() { + return menu.stream().map(Dish::getCalories).reduce(Integer::sum).get(); + } + + private static int calculateTotalCaloriesUsingSum() { + return menu.stream().mapToInt(Dish::getCalories).sum(); + } +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Summarizing.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Summarizing.java new file mode 100644 index 0000000..a1ea80c --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/Summarizing.java @@ -0,0 +1,86 @@ +package com.brianway.learning.java8.streamapi.collect; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.stream.Collectors.averagingInt; +import static java.util.stream.Collectors.counting; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.reducing; +import static java.util.stream.Collectors.summarizingInt; +import static java.util.stream.Collectors.summingInt; + +import java.util.Comparator; +import java.util.IntSummaryStatistics; +import java.util.function.BinaryOperator; + +/** + * 归约和汇总 + */ +public class Summarizing { + + public static void main(String... args) { + System.out.println("Nr. of dishes: " + howManyDishes()); + System.out.println("The most caloric dish is: " + findMostCaloricDish()); + System.out.println("The most caloric dish is: " + findMostCaloricDishUsingComparator()); + System.out.println("Total calories in menu: " + calculateTotalCalories()); + System.out.println("Average calories in menu: " + calculateAverageCalories()); + System.out.println("Menu statistics: " + calculateMenuStatistics()); + System.out.println("Short menu: " + getShortMenu()); + System.out.println("Short menu comma separated: " + getShortMenuCommaSeparated()); + } + + /** + * 统计个数 + */ + private static long howManyDishes() { + return menu.stream().collect(counting()); + } + + /** + * 查找流中最大值 + */ + private static Dish findMostCaloricDish() { + return menu.stream().collect(reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2)).get(); + } + + /** + * 查找流中最大值 + */ + private static Dish findMostCaloricDishUsingComparator() { + Comparator dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories); + BinaryOperator moreCaloricOf = BinaryOperator.maxBy(dishCaloriesComparator); + return menu.stream().collect(reducing(moreCaloricOf)).get(); + } + + /** + * 汇总-求和 + */ + private static int calculateTotalCalories() { + return menu.stream().collect(summingInt(Dish::getCalories)); + } + + /** + * 汇总-求平均数 + */ + private static Double calculateAverageCalories() { + return menu.stream().collect(averagingInt(Dish::getCalories)); + } + + /** + * 汇总-统计值 + */ + private static IntSummaryStatistics calculateMenuStatistics() { + return menu.stream().collect(summarizingInt(Dish::getCalories)); + } + + /** + * 连接字符串 + */ + private static String getShortMenu() { + return menu.stream().map(Dish::getName).collect(joining()); + } + + private static String getShortMenuCommaSeparated() { + return menu.stream().map(Dish::getName).collect(joining(", ")); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/ToListCollector.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/ToListCollector.java new file mode 100644 index 0000000..dd5780e --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/collect/ToListCollector.java @@ -0,0 +1,89 @@ +package com.brianway.learning.java8.streamapi.collect; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.stream.Collector.Characteristics.CONCURRENT; +import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +/** + * 自定义 ToListCollector + * 1.建立新的结果容器: supplier 方法 + * 2.将元素添到结果容器: accumulator 方法 + * 3.对容器应用最终转换: finisher 方法 + * 4.合并两个结果容器: combiner + * 5.characteristics 方法 + */ +public class ToListCollector implements Collector, List> { + + /** + * 创建集合操作的起始点 + */ + @Override + public Supplier> supplier() { + //return () -> new ArrayList(); + return ArrayList::new; + } + + /** + * 累积遍历过的项目,原位修改累加器 + */ + @Override + public BiConsumer, T> accumulator() { + //return (list, item) -> list.add(item); + return List::add; + } + + /** + * 恒等函数 + */ + @Override + public Function, List> finisher() { + //return i -> i; + return Function.identity(); + } + + /** + * 修改第一个累加器,将其与第二个累加器的内容合并 + * 返回第一个累加器 + */ + @Override + public BinaryOperator> combiner() { + return (list1, list2) -> { + list1.addAll(list2); + return list1; + }; + } + + /** + * 为收集器添加 IDENTITY_FINISH 和 CONCURRENT 标志 + */ + @Override + public Set characteristics() { + return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH, CONCURRENT)); + } + + public static void main(String[] args) { + List dishes = menu.stream().collect(Collectors.toList()); + System.out.println(dishes); + dishes = menu.stream().collect(new ToListCollector<>()); + System.out.println(dishes); + // 进行自定义收集而不去实现 Collector + dishes = menu.stream().collect( + ArrayList::new, + List::add, + List::addAll); + System.out.println(dishes); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ForkJoinSumCalculator.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ForkJoinSumCalculator.java new file mode 100644 index 0000000..9c93ed7 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ForkJoinSumCalculator.java @@ -0,0 +1,55 @@ +package com.brianway.learning.java8.streamapi.parallel; + +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.RecursiveTask; +import java.util.stream.LongStream; + +/** + * 使用分支/合并框架执行并行求和 + */ +public class ForkJoinSumCalculator extends RecursiveTask { + + public static final long THRESHOLD = 10_000; + + private final long[] numbers; + private final int start; + private final int end; + + public ForkJoinSumCalculator(long[] numbers) { + this(numbers, 0, numbers.length); + } + + private ForkJoinSumCalculator(long[] numbers, int start, int end) { + this.numbers = numbers; + this.start = start; + this.end = end; + } + + @Override + protected Long compute() { + int length = end - start; + if (length <= THRESHOLD) { + return computeSequentially(); + } + ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2); + leftTask.fork(); + ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end); + Long rightResult = rightTask.compute(); + Long leftResult = leftTask.join(); + return leftResult + rightResult; + } + + private long computeSequentially() { + long sum = 0; + for (int i = start; i < end; i++) { + sum += numbers[i]; + } + return sum; + } + + public static long forkJoinSum(long n) { + long[] numbers = LongStream.rangeClosed(1, n).toArray(); + ForkJoinTask task = new ForkJoinSumCalculator(numbers); + return ParallelStreamsHarness.FORK_JOIN_POOL.invoke(task); + } +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ParallelStreams.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ParallelStreams.java new file mode 100644 index 0000000..78acf26 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ParallelStreams.java @@ -0,0 +1,71 @@ +package com.brianway.learning.java8.streamapi.parallel; + +import java.util.stream.LongStream; +import java.util.stream.Stream; + +/** + * 并行流计算 1~n 的和 + * 分别使用指令式,串行迭代流,并行迭代流,基本类型流,有副作用的流 + */ +public class ParallelStreams { + + /** + * for 循环的迭代 + */ + public static long iterativeSum(long n) { + long result = 0; + for (long i = 0; i <= n; i++) { + result += i; + } + return result; + } + + public static long sequentialSum(long n) { + return Stream.iterate(1L, i -> i + 1).limit(n).reduce(Long::sum).get(); + } + + /** + * iterate 的问题: + * - iterate 生成的是装箱的对象,必须拆成数字才能求和 + * - 很难把 iterate 分成多个独立块来并行执行 + */ + public static long parallelSum(long n) { + return Stream.iterate(1L, i -> i + 1).limit(n).parallel().reduce(Long::sum).get(); + } + + /** + * 使用 LongStream.rangeClosed + * - 没有装箱拆箱 + * - 容易拆分为独立的小块 + */ + public static long rangedSum(long n) { + return LongStream.rangeClosed(1, n).reduce(Long::sum).getAsLong(); + } + + public static long parallelRangedSum(long n) { + return LongStream.rangeClosed(1, n).parallel().reduce(Long::sum).getAsLong(); + } + + public static long sideEffectSum(long n) { + Accumulator accumulator = new Accumulator(); + LongStream.rangeClosed(1, n).forEach(accumulator::add); + return accumulator.total; + } + + /** + * 共享了可变状态,导致每次结果不一致 + */ + public static long sideEffectParallelSum(long n) { + Accumulator accumulator = new Accumulator(); + LongStream.rangeClosed(1, n).parallel().forEach(accumulator::add); + return accumulator.total; + } + + public static class Accumulator { + private long total = 0; + + public void add(long value) { + total += value; + } + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ParallelStreamsHarness.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ParallelStreamsHarness.java new file mode 100644 index 0000000..cbdb86e --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/ParallelStreamsHarness.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java8.streamapi.parallel; + +import java.util.concurrent.ForkJoinPool; +import java.util.function.Function; + +/** + * 测量流性能 + */ +public class ParallelStreamsHarness { + + public static final ForkJoinPool FORK_JOIN_POOL = new ForkJoinPool(); + + public static void main(String[] args) { + System.out.println("Iterative Sum done in: " + measurePerf(ParallelStreams::iterativeSum, 10_000_000L) + " msecs"); + System.out.println("Sequential Sum done in: " + measurePerf(ParallelStreams::sequentialSum, 10_000_000L) + " msecs"); + System.out.println("Parallel forkJoinSum done in: " + measurePerf(ParallelStreams::parallelSum, 10_000_000L) + " msecs"); + System.out.println("Range forkJoinSum done in: " + measurePerf(ParallelStreams::rangedSum, 10_000_000L) + " msecs"); + System.out.println("Parallel range forkJoinSum done in: " + measurePerf(ParallelStreams::parallelRangedSum, 10_000_000L) + " msecs"); + System.out.println("ForkJoin sum done in: " + measurePerf(ForkJoinSumCalculator::forkJoinSum, 10_000_000L) + " msecs"); + System.out.println("SideEffect sum done in: " + measurePerf(ParallelStreams::sideEffectSum, 10_000_000L) + " msecs"); + System.out.println("SideEffect prallel sum done in: " + measurePerf(ParallelStreams::sideEffectParallelSum, 10_000_000L) + " msecs"); + } + + public static long measurePerf(Function f, T input) { + long fastest = Long.MAX_VALUE; + for (int i = 0; i < 10; i++) { + long start = System.nanoTime(); + R result = f.apply(input); + long duration = (System.nanoTime() - start) / 1_000_000; + System.out.println("Result: " + result); + if (duration < fastest) fastest = duration; + } + return fastest; + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/WordCount.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/WordCount.java new file mode 100644 index 0000000..ccafa48 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/parallel/WordCount.java @@ -0,0 +1,120 @@ +package com.brianway.learning.java8.streamapi.parallel; + +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * Spliterator: splitable iterator + */ +public class WordCount { + + public static final String SENTENCE = + " Nel mezzo del cammin di nostra vita " + + "mi ritrovai in una selva oscura" + + " che la dritta via era smarrita "; + + public static void main(String[] args) { + System.out.println("Found " + countWordsIteratively(SENTENCE) + " words"); + System.out.println("Found " + countWords(SENTENCE) + " words"); + } + + public static int countWordsIteratively(String s) { + int counter = 0; + boolean lastSpace = true; + for (char c : s.toCharArray()) { + if (Character.isWhitespace(c)) { + lastSpace = true; + } else { + if (lastSpace) counter++; + lastSpace = false; + } + } + return counter; + } + + public static int countWords(String s) { +// Stream stream = IntStream.range(0, s.length()) +// .mapToObj(SENTENCE::charAt).parallel(); + Spliterator spliterator = new WordCounterSpliterator(s); + Stream stream = StreamSupport.stream(spliterator, true); + + return countWords(stream); + } + + private static int countWords(Stream stream) { + WordCounter wordCounter = stream.reduce(new WordCounter(0, true), + WordCounter::accumulate, + WordCounter::combine); + return wordCounter.getCounter(); + } + + private static class WordCounter { + private final int counter; + private final boolean lastSpace; + + public WordCounter(int counter, boolean lastSpace) { + this.counter = counter; + this.lastSpace = lastSpace; + } + + public WordCounter accumulate(Character c) { + if (Character.isWhitespace(c)) { + return lastSpace ? this : new WordCounter(counter, true); + } else { + return lastSpace ? new WordCounter(counter + 1, false) : this; + } + } + + public WordCounter combine(WordCounter wordCounter) { + return new WordCounter(counter + wordCounter.counter, wordCounter.lastSpace); + } + + public int getCounter() { + return counter; + } + } + + private static class WordCounterSpliterator implements Spliterator { + + private final String string; + private int currentChar = 0; + + private WordCounterSpliterator(String string) { + this.string = string; + } + + @Override + public boolean tryAdvance(Consumer action) { + action.accept(string.charAt(currentChar++)); + return currentChar < string.length(); + } + + @Override + public Spliterator trySplit() { + int currentSize = string.length() - currentChar; + if (currentSize < 10) { + return null; + } + for (int splitPos = currentSize / 2 + currentChar; splitPos < string.length(); splitPos++) { + if (Character.isWhitespace(string.charAt(splitPos))) { + Spliterator spliterator = new WordCounterSpliterator(string.substring(currentChar, splitPos)); + currentChar = splitPos; + return spliterator; + } + } + return null; + } + + @Override + public long estimateSize() { + return string.length() - currentChar; + } + + @Override + public int characteristics() { + return ORDERED + SIZED + SUBSIZED + NONNULL + IMMUTABLE; + } + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/PuttingIntoPractice.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/PuttingIntoPractice.java new file mode 100644 index 0000000..d9384ec --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/PuttingIntoPractice.java @@ -0,0 +1,88 @@ +package com.brianway.learning.java8.streamapi.practice; + +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.toList; + +import java.util.Arrays; +import java.util.List; + +/** + * 各种流操作的使用示例 + */ +public class PuttingIntoPractice { + public static void main(String... args) { + Trader raoul = new Trader("Raoul", "Cambridge"); + Trader mario = new Trader("Mario", "Milan"); + Trader alan = new Trader("Alan", "Cambridge"); + Trader brian = new Trader("Brian", "Cambridge"); + + List transactions = Arrays.asList( + new Transaction(brian, 2011, 300), + new Transaction(raoul, 2012, 1000), + new Transaction(raoul, 2011, 400), + new Transaction(mario, 2012, 710), + new Transaction(mario, 2012, 700), + new Transaction(alan, 2012, 950) + ); + + // Query 1: Find all transactions from year 2011 and sort them by value (small to high). + List tr2011 = transactions.stream() + .filter(transaction -> transaction.getYear() == 2011) + .sorted(comparing(Transaction::getValue)) + .collect(toList()); + System.out.println(tr2011); + + // Query 2: What are all the unique cities where the traders work? + List cities = + transactions.stream() + .map(transaction -> transaction.getTrader().getCity()) + .distinct() + .collect(toList()); + System.out.println(cities); + + // Query 3: Find all traders from Cambridge and sort them by name. + + List traders = + transactions.stream() + .map(Transaction::getTrader) + .filter(trader -> trader.getCity().equals("Cambridge")) + .distinct() + .sorted(comparing(Trader::getName)) + .collect(toList()); + System.out.println(traders); + + // Query 4: Return a string of all traders’ names sorted alphabetically. + + String traderStr = + transactions.stream() + .map(transaction -> transaction.getTrader().getName()) + .distinct() + .sorted() + .reduce("", (n1, n2) -> n1 + n2); + System.out.println(traderStr); + + // Query 5: Are there any trader based in Milan? + + boolean milanBased = + transactions.stream() + .anyMatch(transaction -> transaction.getTrader() + .getCity() + .equals("Milan") + ); + System.out.println(milanBased); + + // Query 6: Update all transactions so that the traders from Milan are set to Cambridge. + transactions.stream() + .map(Transaction::getTrader) + .filter(trader -> trader.getCity().equals("Milan")) + .forEach(trader -> trader.setCity("Cambridge")); + System.out.println(transactions); + + // Query 7: What's the highest value in all the transactions? + int highestValue = + transactions.stream() + .map(Transaction::getValue) + .reduce(0, Integer::max); + System.out.println(highestValue); + } +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/Trader.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/Trader.java new file mode 100644 index 0000000..059c1d7 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/Trader.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java8.streamapi.practice; + +public class Trader { + + private String name; + private String city; + + public Trader(String n, String c) { + this.name = n; + this.city = c; + } + + public String getName() { + return this.name; + } + + public String getCity() { + return this.city; + } + + public void setCity(String newCity) { + this.city = newCity; + } + + public String toString() { + return "Trader:" + this.name + " in " + this.city; + } +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/Transaction.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/Transaction.java new file mode 100644 index 0000000..f9c4458 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/practice/Transaction.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java8.streamapi.practice; + +public class Transaction { + + private Trader trader; + private int year; + private int value; + + public Transaction(Trader trader, int year, int value) { + this.trader = trader; + this.year = year; + this.value = value; + } + + public Trader getTrader() { + return this.trader; + } + + public int getYear() { + return this.year; + } + + public int getValue() { + return this.value; + } + + public String toString() { + return "{" + this.trader + ", " + + "year: " + this.year + ", " + + "value:" + this.value + "}"; + } +} \ No newline at end of file diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Filtering.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Filtering.java new file mode 100644 index 0000000..859dd24 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Filtering.java @@ -0,0 +1,54 @@ +package com.brianway.learning.java8.streamapi.usage; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.stream.Collectors.toList; + +import java.util.Arrays; +import java.util.List; + +/** + * 筛选 + * - 谓词筛选:filter + * - 筛选互异的元素:distinct + * - 忽略头几个元素:limit + * - 截短至指定长度:skip + */ +public class Filtering { + + public static void main(String... args) { + + // Filtering with predicate + List vegetarianMenu = + menu.stream() + .filter(Dish::isVegetarian) + .collect(toList()); + + vegetarianMenu.forEach(System.out::println); + + // Filtering unique elements + List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); + numbers.stream() + .filter(i -> i % 2 == 0) + .distinct() + .forEach(System.out::println); + + // Truncating a stream + List dishesLimit3 = + menu.stream() + .filter(d -> d.getCalories() > 300) + .limit(3) + .collect(toList()); + + dishesLimit3.forEach(System.out::println); + + // Skipping elements + List dishesSkip2 = + menu.stream() + .filter(d -> d.getCalories() > 300) + .skip(2) + .collect(toList()); + + dishesSkip2.forEach(System.out::println); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Finding.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Finding.java new file mode 100644 index 0000000..25b4845 --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Finding.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java8.streamapi.usage; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; + +import java.util.Optional; + +/** + * 查找和匹配 + */ +public class Finding { + + public static void main(String... args) { + if (isVegetarianFriendlyMenu()) { + System.out.println("Vegetarian friendly"); + } + + System.out.println(isHealthyMenu()); + System.out.println(isHealthyMenu2()); + + Optional dish = findVegetarianDish(); + dish.ifPresent(d -> System.out.println(d.getName())); + } + + private static boolean isVegetarianFriendlyMenu() { + return menu.stream().anyMatch(Dish::isVegetarian); + } + + private static boolean isHealthyMenu() { + return menu.stream().allMatch(d -> d.getCalories() < 1000); + } + + private static boolean isHealthyMenu2() { + return menu.stream().noneMatch(d -> d.getCalories() >= 1000); + } + + private static Optional findVegetarianDish() { + return menu.stream().filter(Dish::isVegetarian).findAny(); + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Mapping.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Mapping.java new file mode 100644 index 0000000..4187a4a --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Mapping.java @@ -0,0 +1,60 @@ +package com.brianway.learning.java8.streamapi.usage; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; +import static java.util.stream.Collectors.toList; + +import java.util.Arrays; +import java.util.List; + +/** + * 使用流-映射 + * 注意扁平映射 + * flatMap 的效果:各个数组不是分别映射成一个流,而是映射成 流的内容 + */ +public class Mapping { + + public static void main(String... args) { + + // map + List dishNames = menu.stream() + .map(Dish::getName) + .collect(toList()); + System.out.println(dishNames); + + // map + List words = Arrays.asList("Hello", "World"); + List wordLengths = words.stream() + .map(String::length) + .collect(toList()); + System.out.println(wordLengths); + + // flatMap + words.stream() + .flatMap((String line) -> Arrays.stream(line.split(""))) + .distinct() + .forEach(System.out::println); + + // flatMap + List numbers1 = Arrays.asList(1, 2, 3, 4, 5); + List numbers2 = Arrays.asList(6, 7, 8); + List pairs = + numbers1.stream() + .flatMap((Integer i) -> numbers2.stream() + .map((Integer j) -> new int[] {i, j}) + ) + .filter(pair -> (pair[0] + pair[1]) % 3 == 0) + .collect(toList()); + pairs.forEach(pair -> System.out.println("(" + pair[0] + ", " + pair[1] + ")")); + + // flatMap + List pairs2 = numbers1.stream() + .flatMap(i -> numbers2.stream() + .filter(j -> (i + j) % 3 == 0) + .map(j -> new int[] {i, j}) + ) + .collect(toList()); + System.out.println("----------"); + pairs2.forEach(pair -> System.out.println("(" + pair[0] + ", " + pair[1] + ")")); + } +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/NumericStreams.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/NumericStreams.java new file mode 100644 index 0000000..ec6888a --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/NumericStreams.java @@ -0,0 +1,71 @@ +package com.brianway.learning.java8.streamapi.usage; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; + +import java.util.Arrays; +import java.util.List; +import java.util.OptionalInt; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * 数值流 + * 原始类型特化 + * 数值范围 + */ +public class NumericStreams { + + public static void main(String... args) { + + List numbers = Arrays.asList(3, 4, 5, 1, 2); + + Arrays.stream(numbers.toArray()).forEach(System.out::println); + int calories = menu.stream() + .mapToInt(Dish::getCalories) + .sum(); + System.out.println("Number of calories:" + calories); + + // max and OptionalInt + OptionalInt maxCalories = menu.stream() + .mapToInt(Dish::getCalories) + .max(); + + int max; + if (maxCalories.isPresent()) { + max = maxCalories.getAsInt(); + } else { + // we can choose a default value + max = 1; + } + System.out.println(max); + + // 直接使用 orElse + System.out.print("使用 orElse: "); + System.out.println(maxCalories.orElse(1)); + + // numeric ranges + IntStream evenNumbers = IntStream.rangeClosed(1, 100) + .filter(n -> n % 2 == 0); + + System.out.println(evenNumbers.count()); + + // 勾股数 + Stream pythagoreanTriples = + IntStream.rangeClosed(1, 100) + .boxed() + .flatMap(a -> IntStream.rangeClosed(a, 100) + .filter(b -> isPerfectSquare(a * a + b * b)) + .boxed() + .map(b -> new int[] {a, b, (int) Math.sqrt(a * a + b * b)}) + ); + + pythagoreanTriples.forEach(t -> System.out.println(t[0] + ", " + t[1] + ", " + t[2])); + + } + + public static boolean isPerfectSquare(int n) { + return Math.sqrt(n) % 1 == 0; + } + +} diff --git a/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Reducing.java b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Reducing.java new file mode 100644 index 0000000..51245ca --- /dev/null +++ b/java8/src/main/java/com/brianway/learning/java8/streamapi/usage/Reducing.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java8.streamapi.usage; + +import com.brianway.learning.java8.streamapi.Dish; +import static com.brianway.learning.java8.streamapi.Dish.menu; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * 归约 + */ +public class Reducing { + + public static void main(String... args) { + + List numbers = Arrays.asList(3, 4, 5, 1, 2); + int sum = numbers.stream().reduce(0, (a, b) -> a + b); + System.out.println(sum); + + int sum2 = numbers.stream().reduce(0, Integer::sum); + System.out.println(sum2); + + int max = numbers.stream().reduce(0, Integer::max); + System.out.println(max); + + Optional min = numbers.stream().reduce(Integer::min); + min.ifPresent(System.out::println); + + int calories = menu.stream() + .map(Dish::getCalories) + .reduce(0, Integer::sum); + System.out.println("Number of calories:" + calories); + } +} diff --git a/java8/src/main/resources/data-building.txt b/java8/src/main/resources/data-building.txt new file mode 100644 index 0000000..2230972 --- /dev/null +++ b/java8/src/main/resources/data-building.txt @@ -0,0 +1,2 @@ +The quick brown fox jumped over the lazy dog +The lazy dog jumped over the quick brown fox diff --git a/java8/src/main/resources/data-lambda.txt b/java8/src/main/resources/data-lambda.txt new file mode 100644 index 0000000..20764bb --- /dev/null +++ b/java8/src/main/resources/data-lambda.txt @@ -0,0 +1,5 @@ +Java +8 +Lambdas +In +Action \ No newline at end of file diff --git a/java8/src/test/java/com/brianway/learning/java8/effective/optional/ReadPositiveIntParamTest.java b/java8/src/test/java/com/brianway/learning/java8/effective/optional/ReadPositiveIntParamTest.java new file mode 100644 index 0000000..051e894 --- /dev/null +++ b/java8/src/test/java/com/brianway/learning/java8/effective/optional/ReadPositiveIntParamTest.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java8.effective.optional; + +import static com.brianway.learning.java8.effective.optional.ReadPositiveIntParam.readDurationImperative; +import static com.brianway.learning.java8.effective.optional.ReadPositiveIntParam.readDurationWithOptional; +import static junit.framework.TestCase.assertEquals; +import org.junit.Test; + +import java.util.Properties; + +/** + * Created by brian on 17/3/27. + */ +public class ReadPositiveIntParamTest { + @Test + public void testMap() { + Properties props = new Properties(); + props.setProperty("a", "5"); + props.setProperty("b", "true"); + props.setProperty("c", "-3"); + + assertEquals(5, readDurationImperative(props, "a")); + assertEquals(0, readDurationImperative(props, "b")); + assertEquals(0, readDurationImperative(props, "c")); + assertEquals(0, readDurationImperative(props, "d")); + + assertEquals(5, readDurationWithOptional(props, "a")); + assertEquals(0, readDurationWithOptional(props, "b")); + assertEquals(0, readDurationWithOptional(props, "c")); + assertEquals(0, readDurationWithOptional(props, "d")); + } + +} diff --git a/pom.xml b/pom.xml index 0ec62fb..5965258 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,9 @@ UTF-8 UTF-8 - 4.11 + 1.8 + 1.8 + 4.13.1 @@ -46,6 +48,10 @@ java-multithread java-base + java-container + java-io + java8 + java-jvm @@ -59,6 +65,4 @@ - - \ No newline at end of file