diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2864663 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Eclipse +.classpath +.project +.settings/ + +# Intellij +.idea/ +*.iml +*.iws + +# Mac +.DS_Store + +# Maven +log/ +target/ +out/ + +# Others +bin/ +.myeclipse +.hprof \ No newline at end of file diff --git a/README.md b/README.md index 4266610..1c21ea6 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,79 @@ -# 我的java学习笔记 +# 我的 Java 学习笔记 -笔记分为两大部分:javase和javaweb +旨在打造在线最佳的 Java 学习笔记,笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解 Java 基础语法,想进一步深入学习的人 -- [javase](/javase) -- [javaweb](/javaweb) +含**博客讲解**和**源码实例**,采用 maven 构建,分模块学习,涉及反射,代理,多线程,IO,集合类等核心知识。 +**如果觉得不错,请先在这个仓库上点个 star 吧**,这也是对我的肯定和鼓励,谢谢了。 -笔记内容主要是对一些基础特性和编程细节进行总结整理,适合了解java基础语法,想进一步深入学习的人 +不定时进行调整和补充,需要关注更新的请 watch、star、fork -**如果觉得不错,请先在这个仓库上点个star吧**,这也是对我的肯定和鼓励,谢谢了。 -不定时进行调整和补充,需要关注更新的请 Watch、Star、Fork +----- + +# 仓库目录 + +**点击相应的模块能看到每个目录的说明文档** + +- [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上观看,访问速度快很多: +# 博客文档 ->* [我的java&javaweb学习笔记(汇总)](http://blog.csdn.net/h3243212/article/details/50659471) ->* [我的java&javaweb学习笔记(汇总)](http://my.oschina.net/brianway/blog/614355) +如果你只是单纯要阅读的话,建议移步 CSDN 或者 oschina 上观看,访问速度快很多: + +>* CSDN:[我的java&javaweb学习笔记(汇总)](http://blog.csdn.net/h3243212/article/details/50659471) +>* oschina:[我的java&javaweb学习笔记(汇总)](http://my.oschina.net/brianway/blog/614355) + + +**博客目录** + +- [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) + - [java基础巩固笔记(4)-代理.md](/blogs/javase/java基础巩固笔记(4)-代理.md) + - [java基础巩固笔记(4)-实现AOP功能的封装与配置的小框架.md](/blogs/javase/java基础巩固笔记(4)-实现AOP功能的封装与配置的小框架.md) + - [java基础巩固笔记(5)-多线程之传统多线程.md](/blogs/javase/java基础巩固笔记(5)-多线程之传统多线程.md) + - [java基础巩固笔记(5)-多线程之共享数据.md](/blogs/javase/java基础巩固笔记(5)-多线程之共享数据.md) + - [java基础巩固笔记(5)-多线程之线程并发库.md](/blogs/javase/java基础巩固笔记(5)-多线程之线程并发库.md) + - [java基础巩固笔记(6)-注解.md](/blogs/javase/java基础巩固笔记(6)-注解.md) +- [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) + - [javaweb入门笔记(4)-request和response.md](/blogs/javaweb/javaweb入门笔记(4)-request和response.md) + - [javaweb入门笔记(5)-cookie和session.md](/blogs/javaweb/javaweb入门笔记(5)-cookie和session.md) + - [javaweb入门笔记(6)-JSP技术.md](/blogs/javaweb/javaweb入门笔记(6)-JSP技术.md) ----- -# 目录 - - - [javase](/javase) - - [java基础巩固笔记(1)-反射.md](/javase/java基础巩固笔记(1)-反射.md) - - [java基础巩固笔记(2)-泛型.md](/javase/java基础巩固笔记(2)-泛型.md) - - [java基础巩固笔记(3)-类加载器.md](/javase/java基础巩固笔记(3)-类加载器.md) - - [java基础巩固笔记(4)-代理.md](/javase/java基础巩固笔记(4)-代理.md) - - [java基础巩固笔记(4)-实现AOP功能的封装与配置的小框架.md](/javase/java基础巩固笔记(4)-实现AOP功能的封装与配置的小框架.md) - - [java基础巩固笔记(5)-多线程之传统多线程.md](/javase/java基础巩固笔记(5)-多线程之传统多线程.md) - - [java基础巩固笔记(5)-多线程之共享数据.md](/javase/java基础巩固笔记(5)-多线程之共享数据.md) - - [java基础巩固笔记(5)-多线程之线程并发库.md](/javase/java基础巩固笔记(5)-多线程之线程并发库.md) - - [java基础巩固笔记(6)-注解.md](/javase/java基础巩固笔记(6)-注解.md) - - [javaweb](/javaweb) - - [javaweb入门笔记(1)-Tomcat.md](/javaweb/javaweb入门笔记(1)-Tomcat.md) - - [javaweb入门笔记(2)-http入门.md](/javaweb/javaweb入门笔记(2)-http入门.md) - - [javaweb入门笔记(3)-Servlet.md](/javaweb/javaweb入门笔记(3)-Servlet.md) - - [javaweb入门笔记(4)-request和response.md](/javaweb/javaweb入门笔记(4)-request和response.md) - - [javaweb入门笔记(5)-cookie和session.md](/javaweb/javaweb入门笔记(5)-cookie和session.md) - - [javaweb入门笔记(6)-JSP技术.md](/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 完成) +* [ ] 原有的 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 完成) ----- @@ -46,10 +81,14 @@ # 联系作者 - [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 + ----- -**All copyright reserved** \ No newline at end of file +# Lisence + +Lisenced under [Apache 2.0 lisence](http://opensource.org/licenses/Apache-2.0) diff --git a/blogs/README.md b/blogs/README.md new file mode 100644 index 0000000..57d6ca8 --- /dev/null +++ b/blogs/README.md @@ -0,0 +1,27 @@ +# 博客 + +如果你只是单纯要阅读的话,建议移步CSDN或者oschina上观看,访问速度快很多: + +>* CSDN:[我的java&javaweb学习笔记(汇总)](http://blog.csdn.net/h3243212/article/details/50659471) +>* oschina:[我的java&javaweb学习笔记(汇总)](http://my.oschina.net/brianway/blog/614355) + + +# 目录 + +- [javase](/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) + - [java基础巩固笔记(4)-代理.md](/blogs/javase/java基础巩固笔记(4)-代理.md) + - [java基础巩固笔记(4)-实现AOP功能的封装与配置的小框架.md](/blogs/javase/java基础巩固笔记(4)-实现AOP功能的封装与配置的小框架.md) + - [java基础巩固笔记(5)-多线程之传统多线程.md](/blogs/javase/java基础巩固笔记(5)-多线程之传统多线程.md) + - [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) + - [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) + - [javaweb入门笔记(4)-request和response.md](/blogs/javaweb/javaweb入门笔记(4)-request和response.md) + - [javaweb入门笔记(5)-cookie和session.md](/blogs/javaweb/javaweb入门笔记(5)-cookie和session.md) + - [javaweb入门笔记(6)-JSP技术.md](/blogs/javaweb/javaweb入门笔记(6)-JSP技术.md) \ No newline at end of file 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/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" similarity index 93% rename from "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" rename to "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/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/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" similarity index 97% rename from "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" rename to "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/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/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" similarity index 93% rename from "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" rename to "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/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/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" similarity index 95% rename from "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" rename to "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/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/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\345\256\236\347\216\260AOP\345\212\237\350\203\275\347\232\204\345\260\201\350\243\205\344\270\216\351\205\215\347\275\256\347\232\204\345\260\217\346\241\206\346\236\266.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\345\256\236\347\216\260AOP\345\212\237\350\203\275\347\232\204\345\260\201\350\243\205\344\270\216\351\205\215\347\275\256\347\232\204\345\260\217\346\241\206\346\236\266.md" similarity index 100% rename from "javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\345\256\236\347\216\260AOP\345\212\237\350\203\275\347\232\204\345\260\201\350\243\205\344\270\216\351\205\215\347\275\256\347\232\204\345\260\217\346\241\206\346\236\266.md" rename to "blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(4)-\345\256\236\347\216\260AOP\345\212\237\350\203\275\347\232\204\345\260\201\350\243\205\344\270\216\351\205\215\347\275\256\347\232\204\345\260\217\346\241\206\346\236\266.md" diff --git "a/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\344\274\240\347\273\237\345\244\232\347\272\277\347\250\213.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\344\274\240\347\273\237\345\244\232\347\272\277\347\250\213.md" similarity index 100% rename from "javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\344\274\240\347\273\237\345\244\232\347\272\277\347\250\213.md" rename to "blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\344\274\240\347\273\237\345\244\232\347\272\277\347\250\213.md" diff --git "a/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\345\205\261\344\272\253\346\225\260\346\215\256.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\345\205\261\344\272\253\346\225\260\346\215\256.md" similarity index 100% rename from "javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\345\205\261\344\272\253\346\225\260\346\215\256.md" rename to "blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\345\205\261\344\272\253\346\225\260\346\215\256.md" diff --git "a/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\347\272\277\347\250\213\345\271\266\345\217\221\345\272\223.md" "b/blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\347\272\277\347\250\213\345\271\266\345\217\221\345\272\223.md" similarity index 100% rename from "javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\347\272\277\347\250\213\345\271\266\345\217\221\345\272\223.md" rename to "blogs/javase/java\345\237\272\347\241\200\345\267\251\345\233\272\347\254\224\350\256\260(5)-\345\244\232\347\272\277\347\250\213\344\271\213\347\272\277\347\250\213\345\271\266\345\217\221\345\272\223.md" diff --git "a/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" similarity index 99% rename from "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" rename to "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/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/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" similarity index 96% rename from "javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(1)-Tomcat.md" rename to "blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(1)-Tomcat.md" index cf97372..68ab208 100644 --- "a/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/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" similarity index 97% rename from "javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(2)-http\345\205\245\351\227\250.md" rename to "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/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/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" similarity index 96% rename from "javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(3)-Servlet.md" rename to "blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(3)-Servlet.md" index 06c051f..e43df2f 100644 --- "a/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/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(4)-request\345\222\214response.md" "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(4)-request\345\222\214response.md" similarity index 100% rename from "javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(4)-request\345\222\214response.md" rename to "blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(4)-request\345\222\214response.md" diff --git "a/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(5)-cookie\345\222\214session.md" "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(5)-cookie\345\222\214session.md" similarity index 100% rename from "javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(5)-cookie\345\222\214session.md" rename to "blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(5)-cookie\345\222\214session.md" diff --git "a/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(6)-JSP\346\212\200\346\234\257.md" "b/blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(6)-JSP\346\212\200\346\234\257.md" similarity index 100% rename from "javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(6)-JSP\346\212\200\346\234\257.md" rename to "blogs/javaweb/javaweb\345\205\245\351\227\250\347\254\224\350\256\260(6)-JSP\346\212\200\346\234\257.md" diff --git a/java-base/pom.xml b/java-base/pom.xml new file mode 100644 index 0000000..c6536e9 --- /dev/null +++ b/java-base/pom.xml @@ -0,0 +1,14 @@ + + + + java-learning + com.brianway.learning.java + 1.0-SNAPSHOT + + 4.0.0 + + 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/HelloWorld.java b/java-base/src/main/java/com/brianway/learning/java/base/HelloWorld.java new file mode 100644 index 0000000..bd6a35e --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/HelloWorld.java @@ -0,0 +1,10 @@ +package com.brianway.learning.java.base; + +/** + * Created by Brian on 2016/4/13. + */ +public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello World"); + } +} 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 new file mode 100644 index 0000000..4ccca61 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/constructor/FatherClass.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.base.constructor; + +/** + * Created by Brian on 2016/4/14. + */ +public class FatherClass { + protected static int count = 10; + private String name; + + static { + System.out.println("父类的静态属性count初始化:" + count); + } + + public FatherClass() { + System.out.println("执行了父类的无参构造方法"); + } + + public FatherClass(String name) { + this.name = 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 new file mode 100644 index 0000000..6ea4cb4 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/constructor/SonClass.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.base.constructor; + +/** + * Created by Brian on 2016/4/14. + * + * 构造方法调用问题 + * 子类构造方法会首先默认调用父类的无参构造方法,无论是否显式写了super(); + */ +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) " + name); + } + + public SonClass() { + System.out.println("执行了子类的无参构造方法"); + } + + public static void main(String[] args) { + new SonClass("aaa"); + new SonClass(); + } + +} + +/* +父类的静态属性count初始化:10 +子类可以访问父类的静态属性count 10 +子类的静态属性countSon初始化:0 +执行了父类的无参构造方法 +执行了子类的构造方法SonClass(String name) aaa +执行了父类的无参构造方法 +执行了子类的无参构造方法 + */ diff --git a/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java b/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java new file mode 100644 index 0000000..8ac8da7 --- /dev/null +++ b/java-base/src/main/java/com/brianway/learning/java/base/datatype/Boxing.java @@ -0,0 +1,40 @@ +package com.brianway.learning.java.base.datatype; + +/** + * Created by Brian on 2016/4/14. + * + * TODO 有些细节待理解 + * + * 主要是考装箱和拆箱 + */ +public class Boxing { + public static void main(String[] args) { + Integer a = 1; + Integer b = 2; + Integer c = 3; + Integer d = 3; + Integer e = 321; + Integer f = 321; + Long g = 3L; + System.out.println(c == d); + System.out.println(e == f); + System.out.println(c == (a + b)); + 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 调用 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 new file mode 100644 index 0000000..c9f06fe --- /dev/null +++ b/java-multithread/pom.xml @@ -0,0 +1,21 @@ + + + + java-learning + com.brianway.learning.java + 1.0-SNAPSHOT + + 4.0.0 + + java-multithread + + + + junit + junit + + + + \ 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 new file mode 100644 index 0000000..0411280 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/MyList.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example1; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Brian on 2016/4/13. + */ +public class MyList { + private List list = new ArrayList(); + + public void add() { + list.add("brian"); + } + + 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 new file mode 100644 index 0000000..6874adb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/Run1_TwoThreadTransData.java @@ -0,0 +1,60 @@ +package com.brianway.learning.java.multithread.communication.example1; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P134 + * 不使用等待/通知机制实现线程间通信 + * + * 这里有可见性的问题,并不一定能看到线程b退出。 + */ +public class Run1_TwoThreadTransData { + public static void main(String[] args) { + MyList service = new MyList(); + ThreadA a = new ThreadA(service); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(service); + b.setName("B"); + b.start(); + } + +} + + +/* +在ThreadB的run方法while里加上synchronized ("any"){} + +输出: +添加了1元素 +添加了2元素 +添加了3元素 +添加了4元素 +java.lang.InterruptedException + at com.brianway.learning.java.multithread.communication.example1.ThreadB.run(ThreadB.java:22) +添加了5元素 +达到size了,线程b要退出了 +添加了6元素 +添加了7元素 +添加了8元素 +添加了9元素 +添加了10元素 + + +---------------- +若不加synchronized ("any"){} + +输出: +添加了1元素 +添加了2元素 +添加了3元素 +添加了4元素 +添加了5元素 +添加了6元素 +添加了7元素 +添加了8元素 +添加了9元素 +添加了10元素 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..9b8819b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadA.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.communication.example1; + +/** + * Created by Brian on 2016/4/13. + */ +public class ThreadA extends Thread { + private MyList list; + + public ThreadA(MyList list) { + super(); + this.list = list; + } + + @Override + public void run() { + for (int i = 0; i < 10; i++) { + list.add(); + System.out.println("添加了" + (i + 1) + "元素"); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} 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 new file mode 100644 index 0000000..541dea8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example1/ThreadB.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.communication.example1; + +/** + * Created by Brian on 2016/4/13. + */ +public class ThreadB extends Thread { + private MyList list; + + public ThreadB(MyList list) { + super(); + this.list = list; + } + + @Override + public void run() { + try { + while (true) { + //System.out.println("in b while: "+list.size()); + //synchronized ("any"){} + if (list.size() == 5) { + System.out.println("达到size了,线程b要退出了"); + throw new InterruptedException(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} 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 new file mode 100644 index 0000000..417d213 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/C_Thread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example10; + +/** + * Created by Brian on 2016/4/14. + */ +public class C_Thread extends Thread { + private Consumer c; + + public C_Thread(Consumer c) { + super(); + this.c = c; + } + + @Override + public void run() { + 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 new file mode 100644 index 0000000..c5773d0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Consumer.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example10; + +/** + * Created by Brian on 2016/4/14. + */ +public class Consumer { + private MyStack myStack; + + public Consumer(MyStack myStack) { + super(); + this.myStack = myStack; + } + + 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 new file mode 100644 index 0000000..c70bb38 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/MyStack.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.communication.example10; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Brian on 2016/4/14. + */ +public class MyStack { + private List list = new ArrayList(); + + synchronized public void push() { + try { + 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()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public String pop() { + String returnValue = ""; + try { + while (list.size() == 0) { + System.out.println("pop操作中的: " + Thread.currentThread().getName() + " 线程呈wait状态"); + this.wait(); + } + returnValue = list.get(0) + " " + Thread.currentThread().getName(); + list.remove(0); + this.notify(); + System.out.println("pop = " + list.size() + " Mystack的pop方法中 线程" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return returnValue; + } +} 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 new file mode 100644 index 0000000..ef0c576 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/P_Thread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example10; + +/** + * Created by Brian on 2016/4/14. + */ +public class P_Thread extends Thread { + private Producer p; + + public P_Thread(Producer p) { + super(); + this.p = p; + } + + @Override + public void run() { + 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 new file mode 100644 index 0000000..14e6eb2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Producer.java @@ -0,0 +1,18 @@ +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) { + super(); + this.myStack = myStack; + } + + 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 new file mode 100644 index 0000000..286da3f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example10/Run10_oneP_manyC.java @@ -0,0 +1,59 @@ +package com.brianway.learning.java.multithread.communication.example10; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P168 + * 一生产与多消费 + * + * while判断解决条件发生改变时没有得到及时的响应,多个呈wait状态的线程被唤醒的问题 + * 但会出现新的问题:假死 + */ +public class Run10_oneP_manyC { + public static void main(String[] args) { + MyStack myStack = new MyStack(); + Producer p = new Producer(myStack); + + 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; i < cNum; i++) { + consumers[i] = new Consumer(myStack); + } + + for (int i = 0; i < cNum; i++) { + c_threads[i] = new C_Thread(consumers[i]); + } + + for (int i = 0; i < cNum; i++) { + c_threads[i].start(); + } + + } +} + +/* +输出: +push = 1 +push操作中的: Thread-0 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-1 +pop = 0.28218649074189095 Thread-1 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-1 线程呈wait状态 +pop操作中的: Thread-2 线程呈wait状态 +push = 1 +push操作中的: Thread-0 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-3 +pop = 0.26526620276366075 Thread-3 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-3 线程呈wait状态 +pop操作中的: Thread-1 线程呈wait状态 +pop操作中的: Thread-2 线程呈wait状态 +pop操作中的: Thread-5 线程呈wait状态 +pop操作中的: Thread-4 线程呈wait状态 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/C_Thread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/C_Thread.java new file mode 100644 index 0000000..73f6033 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/C_Thread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ +public class C_Thread extends Thread { + private Consumer c; + + public C_Thread(Consumer c) { + super(); + this.c = c; + } + + @Override + public void run() { + while (true) { + c.popService(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Consumer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Consumer.java new file mode 100644 index 0000000..51a5572 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Consumer.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ +public class Consumer { + private MyStack myStack; + + public Consumer(MyStack myStack) { + super(); + this.myStack = myStack; + } + + 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/example11/MyStack.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/MyStack.java new file mode 100644 index 0000000..797ae4b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/MyStack.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.communication.example11; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Brian on 2016/4/14. + */ +public class MyStack { + private List list = new ArrayList(); + + synchronized public void push() { + try { + while (list.size() == 1) { + System.out.println("push操作中的: " + Thread.currentThread().getName() + " 线程呈wait状态"); + this.wait(); + } + list.add(Math.random()); + this.notifyAll(); + System.out.println("push = " + list.size()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public String pop() { + String returnValue = ""; + try { + while (list.size() == 0) { + System.out.println("pop操作中的: " + Thread.currentThread().getName() + " 线程呈wait状态"); + this.wait(); + } + returnValue = list.get(0) + " " + Thread.currentThread().getName(); + list.remove(0); + this.notifyAll(); + System.out.println("pop = " + list.size() + " Mystack的pop方法中 线程" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return returnValue; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/P_Thread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/P_Thread.java new file mode 100644 index 0000000..3ac383f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/P_Thread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ +public class P_Thread extends Thread { + private Producer p; + + public P_Thread(Producer p) { + super(); + this.p = p; + } + + @Override + public void run() { + while (true) { + p.pushService(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Producer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Producer.java new file mode 100644 index 0000000..7abe2c9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Producer.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ +public class Producer { + private MyStack myStack; + + public Producer(MyStack myStack) { + super(); + this.myStack = myStack; + } + + public void pushService() { + myStack.push(); + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_manyC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_manyC.java new file mode 100644 index 0000000..37713a3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_manyC.java @@ -0,0 +1,83 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P170 + * 多生产与多消费 + * + * 一直运行下去 + */ +public class Run11_manyP_manyC { + public static void main(String[] args) { + MyStack myStack = new MyStack(); + + int pNum = 6; + Producer[] producers = new Producer[pNum]; + P_Thread[] p_threads = new P_Thread[pNum]; + + for (int i = 0; i < pNum; i++) { + producers[i] = new Producer(myStack); + } + + for (int i = 0; i < pNum; i++) { + p_threads[i] = new P_Thread(producers[i]); + p_threads[i].start(); + } + + int cNum = 8; + Consumer[] consumers = new Consumer[cNum]; + C_Thread[] c_threads = new C_Thread[cNum]; + + for (int i = 0; i < cNum; i++) { + consumers[i] = new Consumer(myStack); + } + + for (int i = 0; i < cNum; i++) { + c_threads[i] = new C_Thread(consumers[i]); + c_threads[i].start(); + } + + } +} + +/* +输出: +push = 1 +push操作中的: Thread-0 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-13 +pop = 0.7346685371683742 Thread-13 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-9 线程呈wait状态 +pop操作中的: Thread-7 线程呈wait状态 +push = 1 +push操作中的: Thread-5 线程呈wait状态 +push操作中的: Thread-1 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-12 +pop = 0.33456421914779433 Thread-12 Consumer的popService方法中打印pop返回值 +push = 1 +push操作中的: Thread-4 线程呈wait状态 +push操作中的: Thread-3 线程呈wait状态 +push操作中的: Thread-2 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-6 +pop = 0.37570391569907924 Thread-6 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-11 线程呈wait状态 +pop操作中的: Thread-10 线程呈wait状态 +pop操作中的: Thread-8 线程呈wait状态 +pop操作中的: Thread-6 线程呈wait状态 +push = 1 +push操作中的: Thread-2 线程呈wait状态 +push操作中的: Thread-3 线程呈wait状态 +push操作中的: Thread-4 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-12 +pop = 0.20512556002122917 Thread-12 Consumer的popService方法中打印pop返回值 +push = 1 +push操作中的: Thread-1 线程呈wait状态 +push操作中的: Thread-5 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-7 +pop = 0.7027033632078373 Thread-7 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-9 线程呈wait状态 +pop操作中的: Thread-13 线程呈wait状态 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_oneC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_oneC.java new file mode 100644 index 0000000..554cc7c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_manyP_oneC.java @@ -0,0 +1,68 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P169 + * 多生产与一消费 + * notifyAll()代替notify(),将一直运行下去 + */ +public class Run11_manyP_oneC { + public static void main(String[] args) { + MyStack myStack = new MyStack(); + + int pNum = 6; + Producer[] producers = new Producer[pNum]; + P_Thread[] p_threads = new P_Thread[pNum]; + + for (int i = 0; i < pNum; i++) { + producers[i] = new Producer(myStack); + } + + for (int i = 0; i < pNum; i++) { + p_threads[i] = new P_Thread(producers[i]); + p_threads[i].start(); + } + + Consumer c = new Consumer(myStack); + C_Thread c_thread = new C_Thread(c); + c_thread.start(); + + } +} + + +/* +一直运行 +输出: +push = 1 +push操作中的: Thread-3 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-6 +pop = 0.13607547102959971 Thread-6 Consumer的popService方法中打印pop返回值 +push = 1 +push操作中的: Thread-4 线程呈wait状态 +push操作中的: Thread-0 线程呈wait状态 +push操作中的: Thread-1 线程呈wait状态 +push操作中的: Thread-2 线程呈wait状态 +push操作中的: Thread-5 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-6 +pop = 0.3177902565715548 Thread-6 Consumer的popService方法中打印pop返回值 +push = 1 +push操作中的: Thread-3 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-6 +pop = 0.5362657484190372 Thread-6 Consumer的popService方法中打印pop返回值 +push = 1 +push操作中的: Thread-5 线程呈wait状态 +push操作中的: Thread-2 线程呈wait状态 +push操作中的: Thread-1 线程呈wait状态 +push操作中的: Thread-0 线程呈wait状态 +push操作中的: Thread-4 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-6 +pop = 0.014856969053708147 Thread-6 Consumer的popService方法中打印pop返回值 +push = 1 +push操作中的: Thread-3 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-6 +pop = 0.38033601579597587 Thread-6 Consumer的popService方法中打印pop返回值 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_oneP_manyC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_oneP_manyC.java new file mode 100644 index 0000000..8aa0dbd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example11/Run11_oneP_manyC.java @@ -0,0 +1,67 @@ +package com.brianway.learning.java.multithread.communication.example11; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P169 + * 一生产与多消费 + * notifyAll()代替notify(),将一直运行下去 + */ +public class Run11_oneP_manyC { + public static void main(String[] args) { + MyStack myStack = new MyStack(); + Producer p = new Producer(myStack); + + 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; i < cNum; i++) { + consumers[i] = new Consumer(myStack); + } + + for (int i = 0; i < cNum; i++) { + c_threads[i] = new C_Thread(consumers[i]); + } + + for (int i = 0; i < cNum; i++) { + c_threads[i].start(); + } + + } +} + +/* +一直运行 +输出: +Thread-5 线程呈wait状态 +pop操作中的: Thread-1 线程呈wait状态 +pop操作中的: Thread-4 线程呈wait状态 +pop操作中的: Thread-3 线程呈wait状态 +pop操作中的: Thread-2 线程呈wait状态 +push = 1 +push操作中的: Thread-0 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-2 +pop = 0.8265055169880213 Thread-2 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-3 线程呈wait状态 +pop操作中的: Thread-4 线程呈wait状态 +pop操作中的: Thread-1 线程呈wait状态 +pop操作中的: Thread-5 线程呈wait状态 +pop操作中的: Thread-2 线程呈wait状态 +push = 1 +push操作中的: Thread-0 线程呈wait状态 +pop = 0 Mystack的pop方法中 线程Thread-2 +pop = 0.9282185161913705 Thread-2 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-5 线程呈wait状态 +pop操作中的: Thread-1 线程呈wait状态 +pop操作中的: Thread-4 线程呈wait状态 +pop操作中的: Thread-3 线程呈wait状态 +pop操作中的: Thread-2 线程呈wait状态 +push = 1 +push操作中的: Thread-0 线程呈wait状态 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ReadData.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ReadData.java new file mode 100644 index 0000000..906e42c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ReadData.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.communication.example12; + +import java.io.IOException; +import java.io.PipedInputStream; + +/** + * Created by Brian on 2016/4/14. + */ +public class ReadData { + public void readMethod(PipedInputStream input) { + try { + System.out.println("read :"); + byte[] bytes = new byte[20]; + int readLength = input.read(bytes); + while (readLength != -1) { + String newData = new String(bytes, 0, readLength); + System.out.print(newData); + readLength = input.read(bytes); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/Run12_pipeInputOutput.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/Run12_pipeInputOutput.java new file mode 100644 index 0000000..d50e51c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/Run12_pipeInputOutput.java @@ -0,0 +1,66 @@ +package com.brianway.learning.java.multithread.communication.example12; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P173 + * 通过管道进行线程间通信:字节流 + * + * 字符流PipedWriter,PipedReader,同理。 + */ +public class Run12_pipeInputOutput { + public static void main(String[] args) { + try { + WriteData writeData = new WriteData(); + ReadData readData = new ReadData(); + + PipedInputStream inputStream = new PipedInputStream(); + PipedOutputStream outputStream = new PipedOutputStream(); + + //inputStream.connect(outputStream); + outputStream.connect(inputStream); + + ThreadRead threadRead = new ThreadRead(readData, inputStream); + threadRead.start(); + + Thread.sleep(2000); + + ThreadWrite threadWrite = new ThreadWrite(writeData, outputStream); + threadWrite.start(); + + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + + +/* +输出: +read : +write : +123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 +123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 + +-------------- +取消注释//inputStream.connect(outputStream); +输出: +java.io.IOException: Already connected + at java.io.PipedOutputStream.connect(PipedOutputStream.java:100) + at com.brianway.learning.java.multithread.communication.example12.Run12_pipeInputOutput.main(Run12_pipeInputOutput.java:25) + 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:483) + at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ThreadRead.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ThreadRead.java new file mode 100644 index 0000000..505a993 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ThreadRead.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.communication.example12; + +import java.io.PipedInputStream; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadRead extends Thread { + private ReadData read; + private PipedInputStream input; + + public ThreadRead(ReadData read, PipedInputStream input) { + super(); + this.input = input; + this.read = read; + } + + @Override + public void run() { + read.readMethod(input); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ThreadWrite.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ThreadWrite.java new file mode 100644 index 0000000..508ce09 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/ThreadWrite.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.communication.example12; + +import java.io.PipedOutputStream; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadWrite extends Thread { + private WriteData write; + private PipedOutputStream out; + + public ThreadWrite(WriteData write, PipedOutputStream out) { + super(); + this.write = write; + this.out = out; + } + + @Override + public void run() { + write.writeMethod(out); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/WriteData.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/WriteData.java new file mode 100644 index 0000000..16ffc94 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example12/WriteData.java @@ -0,0 +1,25 @@ +package com.brianway.learning.java.multithread.communication.example12; + +import java.io.IOException; +import java.io.PipedOutputStream; + +/** + * Created by Brian on 2016/4/14. + */ +public class WriteData { + public void writeMethod(PipedOutputStream out) { + try { + System.out.println("write :"); + for (int i = 0; i < 300; i++) { + String outData = "" + (i + 1); + out.write(outData.getBytes()); + System.out.print(outData); + } + System.out.println(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/BackupA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/BackupA.java new file mode 100644 index 0000000..15bc3da --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/BackupA.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example13; + +/** + * Created by Brian on 2016/4/14. + */ +public class BackupA extends Thread { + private DBTools dbTools; + + public BackupA(DBTools dbTools) { + super(); + this.dbTools = dbTools; + } + + @Override + public void run() { + dbTools.backupA(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/BackupB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/BackupB.java new file mode 100644 index 0000000..387aa94 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/BackupB.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example13; + +/** + * Created by Brian on 2016/4/14. + */ +public class BackupB extends Thread { + private DBTools dbTools; + + public BackupB(DBTools dbTools) { + super(); + this.dbTools = dbTools; + } + + @Override + public void run() { + dbTools.backupB(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/DBTools.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/DBTools.java new file mode 100644 index 0000000..4409d14 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/DBTools.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.communication.example13; + +/** + * Created by Brian on 2016/4/14. + */ +public class DBTools { + volatile private boolean prevIsA = false; + + synchronized public void backupA() { + try { + while (prevIsA == true) { + wait(); + } + for (int i = 0; i < 5; i++) { + System.out.println("★★★★★"); + } + prevIsA = true; + notifyAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public void backupB() { + try { + while (prevIsA == false) { + wait(); + } + for (int i = 0; i < 5; i++) { + System.out.println("☆☆☆☆☆"); + } + prevIsA = false; + notifyAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/Run13_wait_notify_insert.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/Run13_wait_notify_insert.java new file mode 100644 index 0000000..e8c694e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example13/Run13_wait_notify_insert.java @@ -0,0 +1,226 @@ +package com.brianway.learning.java.multithread.communication.example13; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P177 + * + * 等待/通知,交叉执行 + */ +public class Run13_wait_notify_insert { + public static void main(String[] args) { + DBTools dbTools = new DBTools(); + for (int i = 0; i < 20; i++) { + BackupB output = new BackupB(dbTools); + output.start(); + BackupA input = new BackupA(dbTools); + input.start(); + } + } +} + +/* +输出: +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +★★★★★ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ +☆☆☆☆☆ + */ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_join.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_join.java new file mode 100644 index 0000000..87b067f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_join.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.communication.example14; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P180 + * join示例,阻塞当前线程z,使join所属的线程对象x正常执行run()方法,执行完在继续当前线程z后面的代码 + */ +public class Run14_join { + public static void main(String[] args) { + try { + Run14_Thread t = new Run14_Thread(); + t.start(); + t.join(); + System.out.println("thread执行完后在会打印这句话"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + static class Run14_Thread extends Thread { + @Override + public void run() { + try { + int secondValue = (int) (Math.random() * 10000); + System.out.println(secondValue); + Thread.sleep(secondValue); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} + + +/* +输出: +6690 +thread执行完后在会打印这句话 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinExption.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinExption.java new file mode 100644 index 0000000..9903983 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinExption.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.multithread.communication.example14; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P181 + * join的异常 + * 线程b被中断了,但a还在正常运行 + */ +public class Run14_joinExption { + public static void main(String[] args) { + try { + ThreadB b = new ThreadB(); + b.start(); + Thread.sleep(500); + ThreadC c = new ThreadC(b); + c.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +线程B在catch处打印了 +java.lang.InterruptedException + at java.lang.Object.wait(Native Method) + at java.lang.Thread.join(Thread.java:1245) + at java.lang.Thread.join(Thread.java:1319) + at com.brianway.learning.java.multithread.communication.example14.ThreadB.run(ThreadB.java:12) + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinLong.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinLong.java new file mode 100644 index 0000000..4dee9a2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/Run14_joinLong.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.communication.example14; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P183 + * join(long)设定等待的时间 + * join(long)和sleep(long)运行效果并无区别,但对同步的处理不同。 + */ +public class Run14_joinLong { + public static void main(String[] args) { + try { + Run14_Thread thread = new Run14_Thread(); + thread.start(); + thread.join(2000);//只等2秒 + //Thread.sleep(2000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + static class Run14_Thread extends Thread { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} + + +/* +输出: +begin timer=1460635411651 +end timer=1460635413651 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadA.java new file mode 100644 index 0000000..4534202 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadA.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.communication.example14; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadA extends Thread { + @Override + public void run() { + for (int i = 0; i < Integer.MAX_VALUE; i++) { + String newString = new String(); + Math.random(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadB.java new file mode 100644 index 0000000..9a49d18 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadB.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.communication.example14; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadB extends Thread { + @Override + public void run() { + try { + ThreadA a = new ThreadA(); + a.start(); + a.join(); + System.out.println("线程B在run end处打印了"); + } catch (InterruptedException e) { + System.out.println("线程B在catch处打印了"); + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadC.java new file mode 100644 index 0000000..a4be6c4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example14/ThreadC.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.communication.example14; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadC extends Thread { + + private ThreadB b; + + public ThreadC(ThreadB b) { + super(); + this.b = b; + } + + @Override + public void run() { + b.interrupt(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_joinMore.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_joinMore.java new file mode 100644 index 0000000..2e2e969 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_joinMore.java @@ -0,0 +1,88 @@ +package com.brianway.learning.java.multithread.communication.example15; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * 188 + * 方法join后面的代码提前运行 + */ +public class Run15_joinMore { + public static void main(String[] args) { + try { + ThreadB b = new ThreadB(); + ThreadA a = new ThreadA(b); + a.start(); + b.start(); + b.join(1000); + //for(int i =0;i<100000000;i++){ + // if(i%1000000==0)System.out.print(i); + //} + System.out.println(); + System.out.println("main end timer=" + System.currentTimeMillis() + " threadName=" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + static class ThreadA extends Thread { + private ThreadB b; + + public ThreadA(ThreadB b) { + super(); + this.b = b; + } + + @Override + public void run() { + try { + synchronized (b) { + System.out.println("A begin timer=" + System.currentTimeMillis() + " threadName=" + Thread.currentThread().getName()); + Thread.sleep(3000); + System.out.println("A end timer=" + System.currentTimeMillis() + " threadName=" + Thread.currentThread().getName()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + static class ThreadB extends Thread { + @Override + synchronized public void run() { + try { + System.out.println("B begin timer=" + System.currentTimeMillis() + " threadName=" + Thread.currentThread().getName()); + Thread.sleep(3000); + System.out.println("B end timer=" + System.currentTimeMillis() + " threadName=" + Thread.currentThread().getName()); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + } + +} + +/* +输出: +A begin timer=1460639887068 threadName=Thread-1 +A end timer=1460639890069 threadName=Thread-1 + +B begin timer=1460639890069 threadName=Thread-0 +main end timer=1460639890069 threadName=main +B end timer=1460639893069 threadName=Thread-0 + +--------------------------- + +A begin timer=1460639939829 threadName=Thread-1 +A end timer=1460639942830 threadName=Thread-1 + +main end timer=1460639942830 threadName=main +B begin timer=1460639942830 threadName=Thread-0 +B end timer=1460639945830 threadName=Thread-0 + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep.java new file mode 100644 index 0000000..9dbff6d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.communication.example15; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P185 + * join(long)和sleep(long)的区别 + * sleep(long)方法不释放锁 + */ +public class Run15_join_sleep { + public static void main(String[] args) { + try { + ThreadB b = new ThreadB(); + ThreadA a = new ThreadA(b); + a.start(); + Thread.sleep(1000); + ThreadC c = new ThreadC(b); + c.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +b run begin timer=1460637031625 +b run end timer=1460637036626 +打印了bService timer=1460637037626 + + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep_2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep_2.java new file mode 100644 index 0000000..626626f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/Run15_join_sleep_2.java @@ -0,0 +1,61 @@ +package com.brianway.learning.java.multithread.communication.example15; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P187 + * join(long)和sleep(long)的区别 + * join(long)释放锁 + */ +public class Run15_join_sleep_2 { + public static void main(String[] args) { + try { + ThreadB b = new ThreadB(); + ThreadA2 a = new ThreadA2(b); + a.start(); + Thread.sleep(1000); + ThreadC c = new ThreadC(b); + c.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + static class ThreadA2 extends Thread { + private ThreadB b; + + public ThreadA2(ThreadB b) { + super(); + this.b = b; + } + + @Override + public void run() { + try { + synchronized (b) { + b.start(); + b.join(); + System.out.println("a run before for " + System.currentTimeMillis()); + for (int i = 0; i < 100000000; i++) { + Math.random(); + } + System.out.println("a run end " + System.currentTimeMillis()); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} + +/* +输出: +b run begin timer=1460637677744 +打印了bService timer=1460637678746 +b run end timer=1460637682745 +a run before for 1460637682745 +a run end 1460637684923 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadA.java new file mode 100644 index 0000000..9671260 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadA.java @@ -0,0 +1,25 @@ +package com.brianway.learning.java.multithread.communication.example15; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadA extends Thread { + private ThreadB b; + + public ThreadA(ThreadB b) { + super(); + this.b = b; + } + + @Override + public void run() { + try { + synchronized (b) { + b.start(); + Thread.sleep(6000); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadB.java new file mode 100644 index 0000000..47c37b1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadB.java @@ -0,0 +1,23 @@ +package com.brianway.learning.java.multithread.communication.example15; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadB extends Thread { + @Override + public void run() { + try { + System.out.println("b run begin timer=" + System.currentTimeMillis()); + Thread.sleep(5000); + System.out.println("b run end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public void bService() { + System.out.println("打印了bService timer=" + System.currentTimeMillis()); + } + +} + diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadC.java new file mode 100644 index 0000000..51c4150 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example15/ThreadC.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.communication.example15; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadC extends Thread { + + private ThreadB b; + + public ThreadC(ThreadB b) { + super(); + this.b = b; + } + + @Override + public void run() { + b.bService(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/InheritableThreadLocalExt.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/InheritableThreadLocalExt.java new file mode 100644 index 0000000..c93be32 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/InheritableThreadLocalExt.java @@ -0,0 +1,13 @@ +package com.brianway.learning.java.multithread.communication.example16; + +import java.util.Date; + +/** + * Created by Brian on 2016/4/14. + */ +public class InheritableThreadLocalExt extends InheritableThreadLocal { + @Override + protected Object initialValue() { + return new Date().getTime(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/InheritableThreadLocalExt2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/InheritableThreadLocalExt2.java new file mode 100644 index 0000000..82c5ab2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/InheritableThreadLocalExt2.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example16; + +import java.util.Date; + +/** + * Created by Brian on 2016/4/14. + */ +public class InheritableThreadLocalExt2 extends InheritableThreadLocal { + @Override + protected Object initialValue() { + return new Date().getTime(); + } + + @Override + protected Object childValue(Object parentValue) { + return parentValue + "我在子线程加的~"; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt.java new file mode 100644 index 0000000..9cd887e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P198 + * 类InheritableThreadLocal使用,值继承,子线程从父线程取得值 + */ +public class Run16_InheritableThreadLocalExt { + public static void main(String[] args) { + try { + for (int i = 0; i < 10; i++) { + System.out.println("在Main线程中取值=" + Tools.itl.get()); + Thread.sleep(100); + } + Thread.sleep(5000); + ThreadB b = new ThreadB(); + b.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在Main线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 +在ThreadB线程中取值=1460642917909 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt2.java new file mode 100644 index 0000000..925e767 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_InheritableThreadLocalExt2.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P198 + * 类InheritableThreadLocal使用,值继承再更改 + */ +public class Run16_InheritableThreadLocalExt2 { + public static void main(String[] args) { + try { + for (int i = 0; i < 10; i++) { + System.out.println("在Main线程中取值=" + Tools.itl2.get()); + Thread.sleep(100); + } + Thread.sleep(5000); + ThreadC c = new ThreadC(); + c.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在Main线程中取值=1460642947324 +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ +在ThreadC线程中取值=1460642947324我在子线程加的~ + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_ThreadLocal.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_ThreadLocal.java new file mode 100644 index 0000000..fd94412 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Run16_ThreadLocal.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P196 + * 验证线程变量的隔离性 + */ +public class Run16_ThreadLocal { + public static void main(String[] args) { + try { + for (int i = 0; i < 10; i++) { + System.out.println("在Main线程中取值=" + Tools.tl.get()); + Thread.sleep(100); + } + Thread.sleep(5000); + ThreadA a = new ThreadA(); + a.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在Main线程中取值=1460641860515 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 +在ThreadA线程中取值=1460641866517 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadA.java new file mode 100644 index 0000000..8647e88 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadA.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadA extends Thread { + @Override + public void run() { + try { + for (int i = 0; i < 10; i++) { + System.out.println("在ThreadA线程中取值=" + Tools.tl.get()); + Thread.sleep(100); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadB.java new file mode 100644 index 0000000..b353c59 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadB.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadB extends Thread { + @Override + public void run() { + try { + for (int i = 0; i < 10; i++) { + System.out.println("在ThreadB线程中取值=" + Tools.itl.get()); + Thread.sleep(100); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadC.java new file mode 100644 index 0000000..4e67562 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadC.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadC extends Thread { + @Override + public void run() { + try { + for (int i = 0; i < 10; i++) { + System.out.println("在ThreadC线程中取值=" + Tools.itl2.get()); + Thread.sleep(100); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadLocalExt.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadLocalExt.java new file mode 100644 index 0000000..6d73954 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/ThreadLocalExt.java @@ -0,0 +1,13 @@ +package com.brianway.learning.java.multithread.communication.example16; + +import java.util.Date; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadLocalExt extends ThreadLocal { + @Override + protected Object initialValue() { + return new Date().getTime(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Tools.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Tools.java new file mode 100644 index 0000000..b8ef7a2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example16/Tools.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.communication.example16; + +/** + * Created by Brian on 2016/4/14. + */ +public class Tools { + public static ThreadLocalExt tl = new ThreadLocalExt(); + public static InheritableThreadLocalExt itl = new InheritableThreadLocalExt(); + public static InheritableThreadLocalExt2 itl2 = new InheritableThreadLocalExt2(); + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_noObjectLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_noObjectLock.java new file mode 100644 index 0000000..8173178 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_noObjectLock.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.multithread.communication.example2; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P137 + * 没有“对象监视器”,调用wait()方法出现运行时异常 + */ +public class Run2_noObjectLock { + public static void main(String[] args) { + String s = new String(""); + try { + s.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +Exception in thread "main" java.lang.IllegalMonitorStateException + at java.lang.Object.wait(Native Method) + at java.lang.Object.wait(Object.java:502) + at com.brianway.learning.java.multithread.communication.example2.Run2_noObjectLock.main(Run2_noObjectLock.java:15) + 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:483) + at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_notify.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_notify.java new file mode 100644 index 0000000..2f12acf --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_notify.java @@ -0,0 +1,40 @@ +package com.brianway.learning.java.multithread.communication.example2; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P139 + * notify实现通知 + * notify调用后,并不会立即释放对象锁,而是退出synchronized代码块后 + * + * 当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象 + * + * @see Thread2 的run方法 + */ +public class Run2_notify { + public static void main(String[] args) { + try { + Object lock = new Object(); + Thread1 t1 = new Thread1(lock); + t1.start(); + Thread.sleep(3000); + Thread2 t2 = new Thread2(lock); + t2.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} + + +/* +输出: +开始 wait time=1460554213416 +开始 notify time=1460554216418 +结束 notify time=1460554218418 +结束 wait time=1460554218418 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_sleep.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_sleep.java new file mode 100644 index 0000000..cf92346 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_sleep.java @@ -0,0 +1,83 @@ +package com.brianway.learning.java.multithread.communication.example2; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P142 + * 测试sleep()期间其他线程是否执行 + * 处理器资源,对象锁,是不同的概念 + */ +public class Run2_sleep { + public static void main(String[] args) { + Thread t1 = new Thread() { + @Override + public void run() { + super.run(); + System.out.println(Thread.currentThread().getName() + " begin sleep"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(Thread.currentThread().getName() + " end sleep"); + } + }; + t1.setName("t1"); + + Thread t2 = new Thread() { + @Override + public void run() { + super.run(); + long i = 0; + long max = (long) Integer.MAX_VALUE; + System.out.println("max = " + max); + + System.out.println(Thread.currentThread().getName() + " begin while"); + while (i < max) { + i++; + if (i % 100000000 == 0) { + System.out.println(Thread.currentThread().getName() + " now is " + i); + } + } + System.out.println(Thread.currentThread().getName() + " end while"); + } + }; + t2.setName("t2"); + + t1.start(); + t2.start(); + + } +} + +/* +输出: +t1 begin sleep +max = 2147483647 +t2 begin while +t2 now is 100000000 +t2 now is 200000000 +t2 now is 300000000 +t2 now is 400000000 +t2 now is 500000000 +t2 now is 600000000 +t2 now is 700000000 +t2 now is 800000000 +t2 now is 900000000 +t2 now is 1000000000 +t2 now is 1100000000 +t2 now is 1200000000 +t2 now is 1300000000 +t2 now is 1400000000 +t2 now is 1500000000 +t1 end sleep +t2 now is 1600000000 +t2 now is 1700000000 +t2 now is 1800000000 +t2 now is 1900000000 +t2 now is 2000000000 +t2 now is 2100000000 +t2 end while + */ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_wait.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_wait.java new file mode 100644 index 0000000..1755ea8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Run2_wait.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.multithread.communication.example2; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P137 + * wait()永远阻塞 + */ +public class Run2_wait { + public static void main(String[] args) { + try { + String lock = new String(); + System.out.println("syn上面"); + synchronized (lock) { + System.out.println("syn第一行,wait前面"); + lock.wait(); + System.out.println("wait下面的代码"); + } + System.out.println("syn下面的代码"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +syn上面 +syn第一行,wait前面 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Thread1.java new file mode 100644 index 0000000..8b68acb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Thread1.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.communication.example2; + +/** + * Created by Brian on 2016/4/13. + */ +public class Thread1 extends Thread { + private Object lock; + + public Thread1(Object lock) { + super(); + this.lock = lock; + } + + @Override + public void run() { + try { + synchronized (lock) { + System.out.println("开始 wait time=" + System.currentTimeMillis()); + lock.wait(); + System.out.println("结束 wait time=" + System.currentTimeMillis()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Thread2.java new file mode 100644 index 0000000..4eb45d5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example2/Thread2.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.communication.example2; + +/** + * Created by Brian on 2016/4/13. + */ +public class Thread2 extends Thread { + private Object lock; + + public Thread2(Object lock) { + super(); + this.lock = lock; + } + + @Override + public void run() { + + synchronized (lock) { + System.out.println("开始 notify time=" + System.currentTimeMillis()); + lock.notify(); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("结束 notify time=" + System.currentTimeMillis()); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/MyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/MyThread.java new file mode 100644 index 0000000..d5313e0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/MyThread.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ +public class MyThread extends Thread { + private Object lock; + + public MyThread(Object lock) { + super(); + this.lock = lock; + } + + @Override + public void run() { + Service service = new Service(); + service.testMethod(lock); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread.java new file mode 100644 index 0000000..77e8e0e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ +public class NotifyThread extends Thread { + private Object lock; + + public NotifyThread(Object lock) { + super(); + this.lock = lock; + } + + @Override + public void run() { + synchronized (lock) { + lock.notify(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread2.java new file mode 100644 index 0000000..c28bba1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread2.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ +public class NotifyThread2 extends Thread { + private Object lock; + + public NotifyThread2(Object lock) { + super(); + this.lock = lock; + } + + @Override + public void run() { + synchronized (lock) { + lock.notify(); + lock.notify(); + lock.notify(); + lock.notify(); + + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread3.java new file mode 100644 index 0000000..de9ab05 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/NotifyThread3.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ +public class NotifyThread3 extends Thread { + private Object lock; + + public NotifyThread3(Object lock) { + super(); + this.lock = lock; + } + + @Override + public void run() { + synchronized (lock) { + lock.notifyAll(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyAll.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyAll.java new file mode 100644 index 0000000..79a8dcd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyAll.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * P150 + * 唤醒多个线程,(逆序?试了好多次,全部都是刚好逆序的。巧合?机制?) + */ +public class Run3_notifyAll { + public static void main(String[] args) throws InterruptedException { + Object lock = new Object(); + MyThread a = new MyThread(lock); + a.start(); + MyThread b = new MyThread(lock); + b.start(); + MyThread c = new MyThread(lock); + c.start(); + + Thread.sleep(1000); + + NotifyThread3 notifyThread = new NotifyThread3(lock); + notifyThread.start(); + } +} + +/* +输出: +begin wait(),ThreadName=Thread-0 +begin wait(),ThreadName=Thread-1 +begin wait(),ThreadName=Thread-2 +end wait(),ThreadName=Thread-2 +end wait(),ThreadName=Thread-1 +end wait(),ThreadName=Thread-0 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyMany.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyMany.java new file mode 100644 index 0000000..5253f05 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyMany.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * P150 + * 通知多个线程 + */ +public class Run3_notifyMany { + public static void main(String[] args) throws InterruptedException { + Object lock = new Object(); + MyThread a = new MyThread(lock); + a.start(); + MyThread b = new MyThread(lock); + b.start(); + MyThread c = new MyThread(lock); + c.start(); + + Thread.sleep(1000); + + NotifyThread2 notifyThread = new NotifyThread2(lock); + notifyThread.start(); + } +} + +/* +输出: +begin wait(),ThreadName=Thread-0 +begin wait(),ThreadName=Thread-2 +begin wait(),ThreadName=Thread-1 +end wait(),ThreadName=Thread-0 +end wait(),ThreadName=Thread-1 +end wait(),ThreadName=Thread-2 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyOne.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyOne.java new file mode 100644 index 0000000..202a9b4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Run3_notifyOne.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * P149 + * 通知一个线程 + */ +public class Run3_notifyOne { + public static void main(String[] args) throws InterruptedException { + Object lock = new Object(); + MyThread a = new MyThread(lock); + a.start(); + MyThread b = new MyThread(lock); + b.start(); + MyThread c = new MyThread(lock); + c.start(); + + Thread.sleep(1000); + + NotifyThread notifyThread = new NotifyThread(lock); + notifyThread.start(); + } +} + +/* +输出: +begin wait(),ThreadName=Thread-1 +begin wait(),ThreadName=Thread-2 +begin wait(),ThreadName=Thread-0 +end wait(),ThreadName=Thread-1 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Service.java new file mode 100644 index 0000000..0de5fe4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example3/Service.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example3; + +/** + * Created by brian on 2016/4/14. + */ +public class Service { + public void testMethod(Object lock) { + try { + synchronized (lock) { + System.out.println("begin wait(),ThreadName=" + Thread.currentThread().getName()); + lock.wait(); + System.out.println("end wait(),ThreadName=" + Thread.currentThread().getName()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam.java new file mode 100644 index 0000000..11fb6e0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.communication.example4; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * p151 + * wait(long)使用,超时自动唤醒 + */ +public class Run4_waitHasParam { + static private Object lock = new Object(); + static private Runnable runnable1 = new Runnable() { + public void run() { + try { + synchronized (lock) { + System.out.println("wait begin timer=" + System.currentTimeMillis()); + lock.wait(4000); + System.out.println("wait end timer=" + System.currentTimeMillis()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + public static void main(String[] args) { + Thread t = new Thread(runnable1); + t.start(); + } +} + + +/* +输出: +wait begin timer=1460566545742 +wait end timer=1460566549743 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam2.java new file mode 100644 index 0000000..4d35cf4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example4/Run4_waitHasParam2.java @@ -0,0 +1,55 @@ +package com.brianway.learning.java.multithread.communication.example4; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * p152 + * wait(long)使用,时间限制内由其他线程唤醒 + */ +public class Run4_waitHasParam2 { + static private Object lock = new Object(); + static private Runnable runnable1 = new Runnable() { + public void run() { + try { + synchronized (lock) { + System.out.println("wait begin timer=" + System.currentTimeMillis()); + lock.wait(5000); + System.out.println("wait end timer=" + System.currentTimeMillis()); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + static private Runnable runnable2 = new Runnable() { + public void run() { + + synchronized (lock) { + System.out.println("notify begin timer=" + System.currentTimeMillis()); + lock.notify(); + System.out.println("notify end timer=" + System.currentTimeMillis()); + } + + } + }; + + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(runnable1); + t1.start(); + Thread.sleep(2000); + Thread t2 = new Thread(runnable2); + t2.start(); + } +} + + +/* +输出: +wait begin timer=1460566507815 +notify begin timer=1460566509815 +notify end timer=1460566509815 +wait end timer=1460566509815 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/MyRun.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/MyRun.java new file mode 100644 index 0000000..a501e72 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/MyRun.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.communication.example5; + +/** + * Created by brian on 2016/4/14. + */ +public class MyRun { + private Object lock = new Object(); + private boolean isFirstRunNotify = false; + public Runnable runnableWait = new Runnable() { + public void run() { + try { + synchronized (lock) { + while (!isFirstRunNotify) { + System.out.println("wait begin timer=" + System.currentTimeMillis()); + lock.wait(); + System.out.println("wait end timer=" + System.currentTimeMillis()); + } + + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + public Runnable runnableNotify = new Runnable() { + public void run() { + + synchronized (lock) { + System.out.println("notify begin timer=" + System.currentTimeMillis()); + lock.notify(); + System.out.println("notify end timer=" + System.currentTimeMillis()); + isFirstRunNotify = true; + } + + } + }; +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notify.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notify.java new file mode 100644 index 0000000..c07641a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notify.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.communication.example5; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * P154 + * notify正常通知 + */ +public class Run5_notify { + public static void main(String[] args) throws InterruptedException { + MyRun myRun = new MyRun(); + Thread a = new Thread(myRun.runnableWait); + a.start(); + Thread.sleep(100); + Thread b = new Thread(myRun.runnableNotify); + b.start(); + } + +} + +/* +输出: +wait begin timer=1460567668037 +notify begin timer=1460567668137 +notify end timer=1460567668137 +wait end timer=1460567668137 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notifyEarly.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notifyEarly.java new file mode 100644 index 0000000..0ed4d99 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example5/Run5_notifyEarly.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java.multithread.communication.example5; + +/** + * Created by brian on 2016/4/14. + */ + +/** + * P154 + * notify通知过早 + */ +public class Run5_notifyEarly { + public static void main(String[] args) throws InterruptedException { + MyRun myRun = new MyRun(); + Thread b = new Thread(myRun.runnableNotify); + b.start(); + Thread.sleep(100); + Thread a = new Thread(myRun.runnableWait); + a.start(); + } + +} + +/* +输出: +notify begin timer=1460567514794 +notify end timer=1460567514794 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Add.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Add.java new file mode 100644 index 0000000..5e81f05 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Add.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example6; + +/** + * Created by Brian on 2016/4/14. + */ +public class Add { + private String lock; + + public Add(String lock) { + super(); + this.lock = lock; + } + + public void add() { + synchronized (lock) { + ValueObject.list.add("anyString"); + lock.notifyAll(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Run6_waitOld.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Run6_waitOld.java new file mode 100644 index 0000000..8276e78 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Run6_waitOld.java @@ -0,0 +1,52 @@ +package com.brianway.learning.java.multithread.communication.example6; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P155 + * wait等待条件变化 + */ +public class Run6_waitOld { + public static void main(String[] args) throws InterruptedException { + String lock = new String(""); + Add add = new Add(lock); + Subtract sub = new Subtract(lock); + ThreadSubtract subtract1 = new ThreadSubtract("sub1", sub); + subtract1.start(); + ThreadSubtract subtract2 = new ThreadSubtract("sub2", sub); + subtract2.start(); + Thread.sleep(1000); + ThreadAdd addThread = new ThreadAdd("add1", add); + addThread.start(); + + } +} + +/* +输出: +begin wait(),ThreadName=sub1 +begin wait(),ThreadName=sub2 +end wait(), ThreadName=sub2 +list size = 0 +end wait(), ThreadName=sub1 +Exception in thread "sub1" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 + at java.util.ArrayList.rangeCheck(ArrayList.java:653) + at java.util.ArrayList.remove(ArrayList.java:492) + at com.brianway.learning.java.multithread.communication.example6.Subtract.subtract(Subtract.java:22) + at com.brianway.learning.java.multithread.communication.example6.ThreadSubtract.run(ThreadSubtract.java:16) + +---------------------------- +Subtract类使用while而不是if的话 +while(ValueObject.list.size() == 0){ +//if(ValueObject.list.size() == 0){ + +输出: +begin wait(),ThreadName=sub1 +begin wait(),ThreadName=sub2 +end wait(), ThreadName=sub2 +list size = 0 +end wait(), ThreadName=sub1 +begin wait(),ThreadName=sub1 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Subtract.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Subtract.java new file mode 100644 index 0000000..1205255 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/Subtract.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java.multithread.communication.example6; + +/** + * Created by Brian on 2016/4/14. + */ +public class Subtract { + private String lock; + + public Subtract(String lock) { + super(); + this.lock = lock; + } + + public void subtract() { + try { + synchronized (lock) { + //while(ValueObject.list.size() == 0){ + if (ValueObject.list.size() == 0) { + System.out.println("begin wait(),ThreadName=" + Thread.currentThread().getName()); + lock.wait(); + System.out.println("end wait(), ThreadName=" + Thread.currentThread().getName()); + } + ValueObject.list.remove(0); + System.out.println("list size = " + ValueObject.list.size()); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ThreadAdd.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ThreadAdd.java new file mode 100644 index 0000000..4139904 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ThreadAdd.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example6; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadAdd extends Thread { + private Add add; + + public ThreadAdd(String name, Add add) { + super(name); + this.add = add; + } + + @Override + public void run() { + add.add(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ThreadSubtract.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ThreadSubtract.java new file mode 100644 index 0000000..aac7f4c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ThreadSubtract.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example6; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadSubtract extends Thread { + private Subtract subtract; + + public ThreadSubtract(String name, Subtract subtract) { + super(name); + this.subtract = subtract; + } + + @Override + public void run() { + subtract.subtract(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ValueObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ValueObject.java new file mode 100644 index 0000000..eb429d1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example6/ValueObject.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.communication.example6; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Brian on 2016/4/14. + */ +public class ValueObject { + public static List list = new ArrayList(); +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/Consumer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/Consumer.java new file mode 100644 index 0000000..7719315 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/Consumer.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.communication.example7; + +/** + * Created by Brian on 2016/4/14. + */ +public class Consumer { + private String lock; + + public Consumer(String lock) { + super(); + this.lock = lock; + } + + public void getValue() { + try { + synchronized (lock) { + if (ValueObject.value.equals("")) { + lock.wait(); + } + System.out.println("get的值是" + ValueObject.value); + ValueObject.value = ""; + lock.notify(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/Run7_ProducerAndConsumer_One.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/Run7_ProducerAndConsumer_One.java new file mode 100644 index 0000000..37703cd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/Run7_ProducerAndConsumer_One.java @@ -0,0 +1,68 @@ +package com.brianway.learning.java.multithread.communication.example7; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P158 + * 生产者/消费者模式,一生产一消费 + */ +public class Run7_ProducerAndConsumer_One { + public static void main(String[] args) { + String lock = new String(""); + Producer producer = new Producer(lock); + Consumer consumer = new Consumer(lock); + ThreadP p = new ThreadP(producer); + ThreadC c = new ThreadC(consumer); + p.start(); + c.start(); + } +} + + +/* +输出: +set的值是1460601163700_5560941389335 +get的值是1460601163700_5560941389335 +set的值是1460601163700_5560941398666 +get的值是1460601163700_5560941398666 +set的值是1460601163700_5560941408308 +get的值是1460601163700_5560941408308 +set的值是1460601163700_5560941417949 +get的值是1460601163700_5560941417949 +set的值是1460601163700_5560941427280 +get的值是1460601163700_5560941427280 +set的值是1460601163700_5560941436921 +get的值是1460601163700_5560941436921 +set的值是1460601163700_5560941446874 +get的值是1460601163700_5560941446874 +set的值是1460601163700_5560941456827 +get的值是1460601163700_5560941456827 +set的值是1460601163700_5560941466468 +get的值是1460601163700_5560941466468 +set的值是1460601163700_5560941477043 +get的值是1460601163700_5560941477043 +set的值是1460601163700_5560941486684 +get的值是1460601163700_5560941486684 +set的值是1460601163700_5560941496326 +get的值是1460601163700_5560941496326 +set的值是1460601163700_5560941507212 +get的值是1460601163700_5560941507212 +set的值是1460601163700_5560941517475 +get的值是1460601163700_5560941517475 +set的值是1460601163700_5560941527428 +get的值是1460601163700_5560941527428 +set的值是1460601163700_5560941537070 +get的值是1460601163700_5560941537070 +set的值是1460601163700_5560941546400 +get的值是1460601163700_5560941546400 +set的值是1460601163700_5560941556042 +get的值是1460601163700_5560941556042 +set的值是1460601163700_5560941565683 +get的值是1460601163700_5560941565683 +set的值是1460601163700_5560941575325 +get的值是1460601163700_5560941575325 +set的值是1460601163700_5560941584656 +get的值是1460601163700_5560941584656 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ThreadC.java new file mode 100644 index 0000000..2e5a452 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ThreadC.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example7; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadC extends Thread { + private Consumer c; + + public ThreadC(Consumer c) { + super(); + this.c = c; + } + + @Override + public void run() { + while (true) { + c.getValue(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ThreadP.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ThreadP.java new file mode 100644 index 0000000..f0d93e3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ThreadP.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example7; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadP extends Thread { + private Producer p; + + public ThreadP(Producer p) { + super(); + this.p = p; + } + + @Override + public void run() { + while (true) { + p.setValue(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ValueObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ValueObject.java new file mode 100644 index 0000000..6291939 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/ValueObject.java @@ -0,0 +1,8 @@ +package com.brianway.learning.java.multithread.communication.example7; + +/** + * Created by Brian on 2016/4/14. + */ +public class ValueObject { + public static String value = ""; +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/producer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/producer.java new file mode 100644 index 0000000..8d0e126 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example7/producer.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.communication.example7; + +/** + * Created by Brian on 2016/4/14. + */ +public class Producer { + private String lock; + + public Producer(String lock) { + super(); + this.lock = lock; + } + + public void setValue() { + try { + synchronized (lock) { + if (!ValueObject.value.equals("")) { + lock.wait(); + } + String value = System.currentTimeMillis() + "_" + System.nanoTime(); + System.out.println("set的值是" + value); + ValueObject.value = value; + lock.notify(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Consumer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Consumer.java new file mode 100644 index 0000000..dd70973 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Consumer.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.communication.example8; + +/** + * Created by Brian on 2016/4/14. + */ +public class Consumer { + private String lock; + + public Consumer(String lock) { + super(); + this.lock = lock; + } + + public void getValue() { + try { + synchronized (lock) { + while (ValueObject.value.equals("")) { + System.out.println("消费者 " + Thread.currentThread().getName() + " WAITING了☆"); + lock.wait(); + } + System.out.println("消费者 " + Thread.currentThread().getName() + " RUNNABLE了"); + ValueObject.value = ""; + lock.notify(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Producer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Producer.java new file mode 100644 index 0000000..45dad89 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Producer.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.communication.example8; + +/** + * Created by Brian on 2016/4/14. + */ +public class Producer { + private String lock; + + public Producer(String lock) { + super(); + this.lock = lock; + } + + public void setValue() { + try { + synchronized (lock) { + while (!ValueObject.value.equals("")) { + System.out.println("生产者 " + Thread.currentThread().getName() + " WAITING了★"); + lock.wait(); + } + System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了"); + String value = System.currentTimeMillis() + "_" + System.nanoTime(); + ValueObject.value = value; + lock.notify(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Run8_allWait.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Run8_allWait.java new file mode 100644 index 0000000..4ba252f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/Run8_allWait.java @@ -0,0 +1,75 @@ +package com.brianway.learning.java.multithread.communication.example8; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P161 + * 多生产与多消费,假死 + * 只需将Producer和Consumer类中的notify()改为notifyAll()即可让程序一直运行下去 + */ +public class Run8_allWait { + public static void main(String[] args) throws InterruptedException { + String lock = new String(""); + Producer producer = new Producer(lock); + Consumer consumer = new Consumer(lock); + ThreadP[] pThread = new ThreadP[2]; + ThreadC[] cThread = new ThreadC[2]; + for (int i = 0; i < 2; i++) { + pThread[i] = new ThreadP(producer); + pThread[i].setName("生产者" + (i + 1)); + cThread[i] = new ThreadC(consumer); + cThread[i].setName("消费者" + (i + 1)); + pThread[i].start(); + cThread[i].start(); + } + + Thread.sleep(5000); + Thread[] threads = new Thread[Thread.currentThread().getThreadGroup().activeCount()]; + Thread.currentThread().getThreadGroup().enumerate(threads); + for (int i = 0; i < threads.length; i++) { + System.out.println(threads[i].getName() + " " + threads[i].getState()); + } + + } +} + +/* +输出: +消费者 消费者1 WAITING了☆ +消费者 消费者2 WAITING了☆ +生产者 生产者1 RUNNABLE了 +生产者 生产者1 WAITING了★ +生产者 生产者2 WAITING了★ +消费者 消费者1 RUNNABLE了 +消费者 消费者1 WAITING了☆ +消费者 消费者2 WAITING了☆ +main RUNNABLE +Monitor Ctrl-Break RUNNABLE +生产者1 WAITING +消费者1 WAITING +生产者2 WAITING +消费者2 WAITING + +---------------------------- + +生产者 生产者1 RUNNABLE了 +生产者 生产者1 WAITING了★ +生产者 生产者2 WAITING了★ +消费者 消费者1 RUNNABLE了 +消费者 消费者1 WAITING了☆ +生产者 生产者1 RUNNABLE了 +生产者 生产者1 WAITING了★ +生产者 生产者2 WAITING了★ +消费者 消费者2 RUNNABLE了 +消费者 消费者2 WAITING了☆ +消费者 消费者1 WAITING了☆ +main RUNNABLE +Monitor Ctrl-Break RUNNABLE +生产者1 WAITING +消费者1 WAITING +生产者2 WAITING +消费者2 WAITING + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ThreadC.java new file mode 100644 index 0000000..4e7106c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ThreadC.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example8; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadC extends Thread { + private Consumer c; + + public ThreadC(Consumer c) { + super(); + this.c = c; + } + + @Override + public void run() { + while (true) { + c.getValue(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ThreadP.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ThreadP.java new file mode 100644 index 0000000..6652f53 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ThreadP.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example8; + +/** + * Created by Brian on 2016/4/14. + */ +public class ThreadP extends Thread { + private Producer p; + + public ThreadP(Producer p) { + super(); + this.p = p; + } + + @Override + public void run() { + while (true) { + p.setValue(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ValueObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ValueObject.java new file mode 100644 index 0000000..9fc4178 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example8/ValueObject.java @@ -0,0 +1,8 @@ +package com.brianway.learning.java.multithread.communication.example8; + +/** + * Created by Brian on 2016/4/14. + */ +public class ValueObject { + public static String value = ""; +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/C_Thread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/C_Thread.java new file mode 100644 index 0000000..91607db --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/C_Thread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example9; + +/** + * Created by Brian on 2016/4/14. + */ +public class C_Thread extends Thread { + private Consumer c; + + public C_Thread(Consumer c) { + super(); + this.c = c; + } + + @Override + public void run() { + while (true) { + c.popService(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Consumer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Consumer.java new file mode 100644 index 0000000..8986574 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Consumer.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example9; + +/** + * Created by Brian on 2016/4/14. + */ +public class Consumer { + private MyStack myStack; + + public Consumer(MyStack myStack) { + super(); + this.myStack = myStack; + } + + 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/example9/MyStack.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/MyStack.java new file mode 100644 index 0000000..2a7ed5b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/MyStack.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.communication.example9; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Brian on 2016/4/14. + */ +public class MyStack { + private List list = new ArrayList(); + + synchronized public void push() { + try { + if (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()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public String pop() { + String returnValue = ""; + try { + if (list.size() == 0) { + System.out.println("pop操作中的: " + Thread.currentThread().getName() + " 线程呈wait状态"); + this.wait(); + } + returnValue = list.get(0) + " " + Thread.currentThread().getName(); + list.remove(0); + this.notify(); + System.out.println("pop = " + list.size() + " Mystack的pop方法中 线程" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return returnValue; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/P_Thread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/P_Thread.java new file mode 100644 index 0000000..a3ef05f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/P_Thread.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.communication.example9; + +/** + * Created by Brian on 2016/4/14. + */ +public class P_Thread extends Thread { + private Producer p; + + public P_Thread(Producer p) { + super(); + this.p = p; + } + + @Override + public void run() { + while (true) { + p.pushService(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Producer.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Producer.java new file mode 100644 index 0000000..c1a6012 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Producer.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.communication.example9; + +/** + * Created by Brian on 2016/4/14. + */ +public class Producer { + private MyStack myStack; + + public Producer(MyStack myStack) { + super(); + this.myStack = myStack; + } + + public void pushService() { + myStack.push(); + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_manyC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_manyC.java new file mode 100644 index 0000000..13f3aed --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_manyC.java @@ -0,0 +1,63 @@ +package com.brianway.learning.java.multithread.communication.example9; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P167 + * 一生产与多消费 + * + * if判断存在弊端,条件发生改变时没有得到及时的响应,多个呈wait状态的线程被唤醒 + * 继而执行list.remove(0)出现异常java.lang.IndexOutOfBoundsException + */ +public class Run9_oneP_manyC { + public static void main(String[] args) { + MyStack myStack = new MyStack(); + Producer p = new Producer(myStack); + Consumer c1 = new Consumer(myStack); + Consumer c2 = new Consumer(myStack); + Consumer c3 = new Consumer(myStack); + Consumer c4 = new Consumer(myStack); + Consumer c5 = new Consumer(myStack); + + P_Thread p_thread = new P_Thread(p); + p_thread.start(); + + C_Thread c_thread1 = new C_Thread(c1); + C_Thread c_thread2 = new C_Thread(c2); + C_Thread c_thread3 = new C_Thread(c3); + C_Thread c_thread4 = new C_Thread(c4); + C_Thread c_thread5 = new C_Thread(c5); + + c_thread1.start(); + c_thread2.start(); + c_thread3.start(); + c_thread4.start(); + c_thread5.start(); + + } +} + +/* +输出: +push = 1 +pop = 0 Mystack的pop方法中 线程Thread-5 +pop = 0.31174265732220185 Thread-5 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-5 线程呈wait状态 +pop操作中的: Thread-1 线程呈wait状态 +pop操作中的: Thread-4 线程呈wait状态 +push = 1 +pop = 0 Mystack的pop方法中 线程Thread-5 +pop = 0.2341485782888254 Thread-5 Consumer的popService方法中打印pop返回值 +pop操作中的: Thread-5 线程呈wait状态 +pop操作中的: Thread-3 线程呈wait状态 +pop操作中的: Thread-2 线程呈wait状态 +Exception in thread "Thread-1" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 + at java.util.ArrayList.rangeCheck(ArrayList.java:653) + at java.util.ArrayList.get(ArrayList.java:429) + at com.brianway.learning.java.multithread.communication.example9.MyStack.pop(MyStack.java:32) + at com.brianway.learning.java.multithread.communication.example9.Consumer.popService(Consumer.java:15) + at com.brianway.learning.java.multithread.communication.example9.C_Thread.run(C_Thread.java:17) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_oneC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_oneC.java new file mode 100644 index 0000000..ee2491c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/communication/example9/Run9_oneP_oneC.java @@ -0,0 +1,39 @@ +package com.brianway.learning.java.multithread.communication.example9; + +/** + * Created by Brian on 2016/4/14. + */ + +/** + * P166 + * 一生产与一消费 + */ +public class Run9_oneP_oneC { + public static void main(String[] args) { + MyStack myStack = new MyStack(); + Producer p = new Producer(myStack); + Consumer c = new Consumer(myStack); + P_Thread p_thread = new P_Thread(p); + C_Thread c_thread = new C_Thread(c); + + p_thread.start(); + c_thread.start(); + } +} + +/* +一直运行 +输出: +push = 1 +pop = 0 Mystack的pop方法中 线程Thread-1 +pop = 0.21477079298150648 Thread-1 Consumer的popService方法中打印pop返回值 +push = 1 +pop = 0 Mystack的pop方法中 线程Thread-1 +pop = 0.09214474637906356 Thread-1 Consumer的popService方法中打印pop返回值 +push = 1 +pop = 0 Mystack的pop方法中 线程Thread-1 +pop = 0.7039441044726136 Thread-1 Consumer的popService方法中打印pop返回值 +push = 1 +pop = 0 Mystack的pop方法中 线程Thread-1 +pop = 0.9344339682446102 Thread-1 Consumer的popService方法中打印pop返回值 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotify.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotify.java new file mode 100644 index 0000000..f1fd746 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotify.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.lock.example1; + +/** + * Created by brian on 2016/4/15. + */ + +/** + * P206 + * 使用Condition实现等待通知 + * Condition对象的await()方法,线程WAITING + */ +public class Run1_UseConditionWaitNotify { + public static void main(String[] args) { + ServiceB service = new ServiceB(); + ThreadB b = new ThreadB(service); + b.start(); + } +} + + +/* +输出: +A + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyError.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyError.java new file mode 100644 index 0000000..6f268f0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyError.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java.multithread.lock.example1; + +/** + * Created by brian on 2016/4/15. + */ + +/** + * P204 + * 使用Condition实现等待通知,展示错误用法 + * IllegalMonitorStateException,监视器出错 + */ +public class Run1_UseConditionWaitNotifyError { + public static void main(String[] args) { + ServiceA service = new ServiceA(); + ThreadA a = new ThreadA(service); + a.start(); + } +} + + +/* +输出: +Exception in thread "Thread-0" java.lang.IllegalMonitorStateException + at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) + at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261) + at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(AbstractQueuedSynchronizer.java:1723) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2036) + at com.brianway.learning.java.multithread.lock.example1.ServiceA.await(ServiceA.java:16) + at com.brianway.learning.java.multithread.lock.example1.ThreadA.run(ThreadA.java:15) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyOk.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyOk.java new file mode 100644 index 0000000..7a26468 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/Run1_UseConditionWaitNotifyOk.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java.multithread.lock.example1; + +/** + * Created by brian on 2016/4/15. + */ + +/** + * P207 + * 正确使用Condition实现等待通知 + * Object类的wait()------Condition类的await() + * Object类的wait(long timeout)------Condition类的await(long time,TimeUnit unit) + * Object类的notify()------Condition类的signal() + * Object类的notifyAll()------Condition类的signalAll() + */ +public class Run1_UseConditionWaitNotifyOk { + public static void main(String[] args) throws InterruptedException { + ServiceC service = new ServiceC(); + ThreadC c = new ThreadC(service); + c.start(); + Thread.sleep(3000); + service.signal(); + } +} + + +/* +输出: +await 时间为1460651340418 +signal时间为1460651343418 +锁释放了 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceA.java new file mode 100644 index 0000000..852b06e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceA.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.lock.example1; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by brian on 2016/4/15. + */ +public class ServiceA { + private Lock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void await() { + try { + condition.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceB.java new file mode 100644 index 0000000..566b932 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceB.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java.multithread.lock.example1; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by brian on 2016/4/15. + */ +public class ServiceB { + private Lock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void waitMethod() { + try { + lock.lock(); + System.out.println("A"); + condition.await(); + System.out.println("B"); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + System.out.println("锁释放了"); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceC.java new file mode 100644 index 0000000..ed0e60e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ServiceC.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.multithread.lock.example1; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by brian on 2016/4/15. + */ +public class ServiceC { + private Lock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void await() { + try { + lock.lock(); + System.out.println("await 时间为" + System.currentTimeMillis()); + condition.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + System.out.println("锁释放了"); + } + } + + public void signal() { + try { + lock.lock(); + System.out.println("signal时间为" + System.currentTimeMillis()); + condition.signal(); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadA.java new file mode 100644 index 0000000..40f3b77 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadA.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example1; + +/** + * Created by brian on 2016/4/15. + */ +public class ThreadA extends Thread { + private ServiceA service; + + public ThreadA(ServiceA service) { + this.service = service; + } + + @Override + public void run() { + service.await(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadB.java new file mode 100644 index 0000000..59291ad --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadB.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example1; + +/** + * Created by brian on 2016/4/15. + */ +public class ThreadB extends Thread { + private ServiceB service; + + public ThreadB(ServiceB service) { + this.service = service; + } + + @Override + public void run() { + service.waitMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadC.java new file mode 100644 index 0000000..b79b80f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example1/ThreadC.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example1; + +/** + * Created by brian on 2016/4/15. + */ +public class ThreadC extends Thread { + private ServiceC service; + + public ThreadC(ServiceC service) { + this.service = service; + } + + @Override + public void run() { + service.await(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin1.java new file mode 100644 index 0000000..89fbfc4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin1.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.lock.example10; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P236 + * 类ReentrantReadWriteLock的使用:读读共享 + */ +public class Run10_ReadWriteLockBegin1 { + public static void main(String[] args) { + final Service1 service = new Service1(); + Thread a = new Thread() { + @Override + public void run() { + service.read(); + } + }; + Thread b = new Thread() { + @Override + public void run() { + service.read(); + } + }; + a.setName("A"); + a.start(); + b.setName("B"); + b.start(); + } +} + + +/* +输出: +获得读锁A 1460726504907 +获得读锁B 1460726504908 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin2.java new file mode 100644 index 0000000..86ba8b8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin2.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.lock.example10; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P238 + * 类ReentrantReadWriteLock的使用:写写互斥 + */ +public class Run10_ReadWriteLockBegin2 { + public static void main(String[] args) { + final Service2 service = new Service2(); + Thread a = new Thread() { + @Override + public void run() { + service.write(); + } + }; + Thread b = new Thread() { + @Override + public void run() { + service.write(); + } + }; + a.setName("A"); + a.start(); + b.setName("B"); + b.start(); + } +} + + +/* +输出: +获得写锁A 1460727106721 +获得写锁B 1460727116721 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin3.java new file mode 100644 index 0000000..3c608ec --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_ReadWriteLockBegin3.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.lock.example10; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P238 + * 类ReentrantReadWriteLock的使用:读写互斥 + */ +public class Run10_ReadWriteLockBegin3 { + public static void main(String[] args) { + final Service3 service = new Service3(); + Thread a = new Thread() { + @Override + public void run() { + service.read(); + } + }; + Thread b = new Thread() { + @Override + public void run() { + service.write(); + } + }; + a.setName("A"); + a.start(); + b.setName("B"); + b.start(); + } +} + + +/* +输出: +获得读锁 A 1460727280066 +获得写锁 B 1460727290067 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_condition.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_condition.java new file mode 100644 index 0000000..0bce4ff --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Run10_condition.java @@ -0,0 +1,152 @@ +package com.brianway.learning.java.multithread.lock.example10; + +/** + * Created by Brian on 2016/4/15. + */ + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * P234 + * Condition实现顺序打印 + * 这里nextPrintWho的volatile关键词去掉也没什么影响 + */ +public class Run10_condition { + volatile private static int nextPrintWho = 1; + private static ReentrantLock lock = new ReentrantLock(); + final private static Condition conditionA = lock.newCondition(); + final private static Condition conditionB = lock.newCondition(); + final private static Condition conditionC = lock.newCondition(); + + public static void main(String[] args) { + Thread a = new Thread() { + @Override + public void run() { + try { + lock.lock(); + while (nextPrintWho != 1) { + conditionA.await(); + } + + for (int i = 0; i < 3; i++) { + System.out.println("ThreadA " + (i + 1)); + } + nextPrintWho = 2; + conditionB.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + }; + + Thread b = new Thread() { + @Override + public void run() { + try { + lock.lock(); + while (nextPrintWho != 2) { + conditionB.await(); + } + for (int i = 0; i < 3; i++) { + System.out.println("ThreadB " + (i + 1)); + } + nextPrintWho = 3; + conditionC.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + }; + + Thread c = new Thread() { + @Override + public void run() { + try { + lock.lock(); + while (nextPrintWho != 3) { + conditionC.await(); + } + for (int i = 0; i < 3; i++) { + System.out.println("ThreadC " + (i + 1)); + } + nextPrintWho = 1; + conditionA.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + }; + + Thread[] aArray = new Thread[5]; + Thread[] bArray = new Thread[5]; + Thread[] cArray = new Thread[5]; + + for (int i = 0; i < 5; i++) { + aArray[i] = new Thread(a); + bArray[i] = new Thread(b); + cArray[i] = new Thread(c); + + aArray[i].start(); + bArray[i].start(); + cArray[i].start(); + } + + } +} + +/* +输出: +ThreadA 1 +ThreadA 2 +ThreadA 3 +ThreadB 1 +ThreadB 2 +ThreadB 3 +ThreadC 1 +ThreadC 2 +ThreadC 3 +ThreadA 1 +ThreadA 2 +ThreadA 3 +ThreadB 1 +ThreadB 2 +ThreadB 3 +ThreadC 1 +ThreadC 2 +ThreadC 3 +ThreadA 1 +ThreadA 2 +ThreadA 3 +ThreadB 1 +ThreadB 2 +ThreadB 3 +ThreadC 1 +ThreadC 2 +ThreadC 3 +ThreadA 1 +ThreadA 2 +ThreadA 3 +ThreadB 1 +ThreadB 2 +ThreadB 3 +ThreadC 1 +ThreadC 2 +ThreadC 3 +ThreadA 1 +ThreadA 2 +ThreadA 3 +ThreadB 1 +ThreadB 2 +ThreadB 3 +ThreadC 1 +ThreadC 2 +ThreadC 3 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service1.java new file mode 100644 index 0000000..72f75d4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service1.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.lock.example10; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * TODO + * 这里为什么用双try? + * 以前不都是直接try catch finally的吗? + */ +public class Service1 { + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + public void read() { + try { + try { + lock.readLock().lock(); + System.out.println("获得读锁" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); + Thread.sleep(10000); + } finally { + lock.readLock().unlock(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service2.java new file mode 100644 index 0000000..cc36a92 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service2.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.lock.example10; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * TODO + * 这里为什么用双try? + * 以前不都是直接try catch finally的吗? + */ +public class Service2 { + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + public void write() { + try { + try { + lock.writeLock().lock(); + System.out.println("获得写锁" + Thread.currentThread().getName() + " " + System.currentTimeMillis()); + Thread.sleep(10000); + } finally { + lock.writeLock().unlock(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service3.java new file mode 100644 index 0000000..c8cfcdd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example10/Service3.java @@ -0,0 +1,44 @@ +package com.brianway.learning.java.multithread.lock.example10; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * TODO + * 这里为什么用双try? + * 以前不都是直接try catch finally的吗? + */ +public class Service3 { + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + public void read() { + try { + try { + lock.readLock().lock(); + System.out.println("获得读锁 " + Thread.currentThread().getName() + " " + System.currentTimeMillis()); + Thread.sleep(10000); + } finally { + lock.readLock().unlock(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void write() { + try { + try { + lock.writeLock().lock(); + System.out.println("获得写锁 " + Thread.currentThread().getName() + " " + System.currentTimeMillis()); + Thread.sleep(10000); + } finally { + lock.writeLock().unlock(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/MyService.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/MyService.java new file mode 100644 index 0000000..4954eb8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/MyService.java @@ -0,0 +1,62 @@ +package com.brianway.learning.java.multithread.lock.example2; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by brian on 2016/4/15. + */ +public class MyService { + private Lock lock = new ReentrantLock(); + private Condition conditionA = lock.newCondition(); + private Condition conditionB = lock.newCondition(); + + public void awaitA() { + try { + lock.lock(); + System.out.println("awaitA begin时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + conditionA.await(); + System.out.println("awaitA end 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + System.out.println("A锁释放了 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + } + } + + public void awaitB() { + try { + lock.lock(); + System.out.println("awaitB begin时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + conditionB.await(); + System.out.println("awaitB end 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + System.out.println("B锁释放了 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + } + } + + public void signalAll_A() { + try { + lock.lock(); + System.out.println("signalAll_A 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + conditionA.signalAll(); + } finally { + lock.unlock(); + } + } + + public void signalAll_B() { + try { + lock.lock(); + System.out.println("signalAll_B 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + conditionB.signalAll(); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/Run2_MustUseMoreCondition.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/Run2_MustUseMoreCondition.java new file mode 100644 index 0000000..1f1f6ec --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/Run2_MustUseMoreCondition.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.lock.example2; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P210 + * 使用多个condition实现通知部分线程 + */ +public class Run2_MustUseMoreCondition { + public static void main(String[] args) throws InterruptedException { + MyService service = new MyService(); + ThreadA a = new ThreadA(service); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(service); + b.setName("B"); + b.start(); + Thread.sleep(3000); + service.signalAll_A(); + } +} + + +/* +输出: +awaitA begin时间为1460687242048 ThreadName=A +awaitB begin时间为1460687242048 ThreadName=B +signalAll_A 时间为1460687245048 ThreadName=main +awaitA end 时间为1460687245048 ThreadName=A +A锁释放了 时间为1460687245048 ThreadName=A + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/ThreadA.java new file mode 100644 index 0000000..bf5e14e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/ThreadA.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example2; + +/** + * Created by Brian on 2016/4/15. + */ +public class ThreadA extends Thread { + private MyService service; + + public ThreadA(MyService service) { + this.service = service; + } + + @Override + public void run() { + service.awaitA(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/ThreadB.java new file mode 100644 index 0000000..0f23c7e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example2/ThreadB.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example2; + +/** + * Created by Brian on 2016/4/15. + */ +public class ThreadB extends Thread { + private MyService service; + + public ThreadB(MyService service) { + this.service = service; + } + + @Override + public void run() { + service.awaitB(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/MyService.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/MyService.java new file mode 100644 index 0000000..16fe7a4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/MyService.java @@ -0,0 +1,52 @@ +package com.brianway.learning.java.multithread.lock.example3; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class MyService { + private ReentrantLock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + private boolean hasValue = false; + + public void set() { + try { + lock.lock(); + while (hasValue == true) { + System.out.println("有可能★★连续" + " 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + condition.await(); + } + System.out.println("打印★" + " 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + hasValue = true; + //condition.signal(); + condition.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + System.out.println("set unlock" + " 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + lock.unlock(); + } + } + + public void get() { + try { + lock.lock(); + while (hasValue == false) { + System.out.println("有可能☆☆连续" + " 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + condition.await(); + } + System.out.println("打印☆" + " 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + hasValue = false; + //condition.signal(); + condition.signalAll(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + System.out.println("get unlock" + " 时间为" + System.currentTimeMillis() + " ThreadName=" + Thread.currentThread().getName()); + lock.unlock(); + } + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/Run3_ConditionManyToMany.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/Run3_ConditionManyToMany.java new file mode 100644 index 0000000..5113188 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/Run3_ConditionManyToMany.java @@ -0,0 +1,81 @@ +package com.brianway.learning.java.multithread.lock.example3; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P215 + * 实现生产者/消费者模式,多对多交替打印 + * signal()会假死 + * signalAll() + */ +public class Run3_ConditionManyToMany { + public static void main(String[] args) { + MyService service = new MyService(); + ThreadA[] threadAs = new ThreadA[10]; + ThreadB[] threadBs = new ThreadB[10]; + for (int i = 0; i < 10; i++) { + threadAs[i] = new ThreadA(service); + threadBs[i] = new ThreadB(service); + threadAs[i].start(); + threadBs[i].start(); + } + } +} + + +/* +输出: +有可能★★连续 时间为1460688833773 ThreadName=Thread-18 +有可能★★连续 时间为1460688833773 ThreadName=Thread-2 +有可能★★连续 时间为1460688833773 ThreadName=Thread-10 +有可能★★连续 时间为1460688833773 ThreadName=Thread-4 +有可能★★连续 时间为1460688833773 ThreadName=Thread-8 +有可能★★连续 时间为1460688833773 ThreadName=Thread-0 +打印☆ 时间为1460688833773 ThreadName=Thread-13 +get unlock 时间为1460688833773 ThreadName=Thread-13 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-13 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-7 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-9 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-11 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-1 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-5 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-15 +打印★ 时间为1460688833773 ThreadName=Thread-6 +set unlock 时间为1460688833773 ThreadName=Thread-6 +有可能★★连续 时间为1460688833773 ThreadName=Thread-6 +有可能★★连续 时间为1460688833773 ThreadName=Thread-12 +有可能★★连续 时间为1460688833773 ThreadName=Thread-16 +有可能★★连续 时间为1460688833773 ThreadName=Thread-14 +打印☆ 时间为1460688833773 ThreadName=Thread-17 +get unlock 时间为1460688833773 ThreadName=Thread-17 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-17 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-3 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-19 +打印★ 时间为1460688833773 ThreadName=Thread-18 +set unlock 时间为1460688833773 ThreadName=Thread-18 +有可能★★连续 时间为1460688833773 ThreadName=Thread-18 +有可能★★连续 时间为1460688833773 ThreadName=Thread-2 +有可能★★连续 时间为1460688833773 ThreadName=Thread-10 +有可能★★连续 时间为1460688833773 ThreadName=Thread-4 +有可能★★连续 时间为1460688833773 ThreadName=Thread-8 +有可能★★连续 时间为1460688833773 ThreadName=Thread-0 +打印☆ 时间为1460688833773 ThreadName=Thread-13 +get unlock 时间为1460688833773 ThreadName=Thread-13 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-13 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-7 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-9 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-11 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-1 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-5 +有可能☆☆连续 时间为1460688833773 ThreadName=Thread-15 +打印★ 时间为1460688833773 ThreadName=Thread-6 +set unlock 时间为1460688833773 ThreadName=Thread-6 +有可能★★连续 时间为1460688833773 ThreadName=Thread-6 +有可能★★连续 时间为1460688833773 ThreadName=Thread-12 +有可能★★连续 时间为1460688833773 ThreadName=Thread-16 +有可能★★连续 时间为1460688833773 ThreadName=Thread-14 +打印☆ 时间为1460688833773 ThreadName=Thread-17 +get unlock 时间为1460688833773 ThreadName=Thread-17 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/ThreadA.java new file mode 100644 index 0000000..12c0475 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/ThreadA.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.lock.example3; + +/** + * Created by Brian on 2016/4/15. + */ +public class ThreadA extends Thread { + private MyService service; + + public ThreadA(MyService service) { + this.service = service; + } + + @Override + public void run() { + for (int i = 0; i < Integer.MAX_VALUE; i++) { + service.set(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/ThreadB.java new file mode 100644 index 0000000..d3ed1eb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example3/ThreadB.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.lock.example3; + +/** + * Created by Brian on 2016/4/15. + */ +public class ThreadB extends Thread { + private MyService service; + + public ThreadB(MyService service) { + this.service = service; + } + + @Override + public void run() { + for (int i = 0; i < Integer.MAX_VALUE; i++) { + service.get(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_Fair.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_Fair.java new file mode 100644 index 0000000..4f45b5d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_Fair.java @@ -0,0 +1,85 @@ +package com.brianway.learning.java.multithread.lock.example4; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P218 + * 公平锁测试 + * 打印结果呈有序状态 + */ +public class Run4_Fair { + public static void main(String[] args) { + final Service service = new Service(true); + + Runnable runnable = new Runnable() { + public void run() { + System.out.println("★线程" + Thread.currentThread().getName() + "运行了"); + service.serviceMethod(); + } + }; + + Thread[] threads = new Thread[10]; + + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(runnable); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + + } +} + + +/* +输出: +★线程Thread-0运行了 +★线程Thread-4运行了 +ThreadName=Thread-0获得锁定 +★线程Thread-3运行了 +★线程Thread-5运行了 +★线程Thread-2运行了 +★线程Thread-1运行了 +★线程Thread-6运行了 +★线程Thread-7运行了 +★线程Thread-8运行了 +ThreadName=Thread-4获得锁定 +ThreadName=Thread-3获得锁定 +★线程Thread-9运行了 +ThreadName=Thread-5获得锁定 +ThreadName=Thread-2获得锁定 +ThreadName=Thread-1获得锁定 +ThreadName=Thread-6获得锁定 +ThreadName=Thread-7获得锁定 +ThreadName=Thread-8获得锁定 +ThreadName=Thread-9获得锁定 + + +------------------------ + + +★线程Thread-0运行了 +★线程Thread-2运行了 +ThreadName=Thread-0获得锁定 +ThreadName=Thread-2获得锁定 +★线程Thread-4运行了 +ThreadName=Thread-4获得锁定 +★线程Thread-6运行了 +ThreadName=Thread-6获得锁定 +★线程Thread-3运行了 +ThreadName=Thread-3获得锁定 +★线程Thread-1运行了 +★线程Thread-7运行了 +★线程Thread-8运行了 +★线程Thread-5运行了 +ThreadName=Thread-1获得锁定 +★线程Thread-9运行了 +ThreadName=Thread-7获得锁定 +ThreadName=Thread-8获得锁定 +ThreadName=Thread-5获得锁定 +ThreadName=Thread-9获得锁定 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_notFair.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_notFair.java new file mode 100644 index 0000000..97a941e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Run4_notFair.java @@ -0,0 +1,81 @@ +package com.brianway.learning.java.multithread.lock.example4; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P218 + * 非公平锁测试 + * 打印结果乱序,先启动的线程不一定先获得锁 + */ +public class Run4_notFair { + public static void main(String[] args) { + final Service service = new Service(false); + + Runnable runnable = new Runnable() { + public void run() { + System.out.println("★线程" + Thread.currentThread().getName() + "运行了"); + service.serviceMethod(); + } + }; + + Thread[] threads = new Thread[10]; + + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(runnable); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + + } +} + + +/* +输出: +★线程Thread-0运行了 +★线程Thread-2运行了 +★线程Thread-4运行了 +★线程Thread-9运行了 +★线程Thread-3运行了 +★线程Thread-1运行了 +★线程Thread-7运行了 +★线程Thread-8运行了 +ThreadName=Thread-0获得锁定 +★线程Thread-6运行了 +ThreadName=Thread-6获得锁定 +★线程Thread-5运行了 +ThreadName=Thread-5获得锁定 +ThreadName=Thread-2获得锁定 +ThreadName=Thread-4获得锁定 +ThreadName=Thread-9获得锁定 +ThreadName=Thread-3获得锁定 +ThreadName=Thread-1获得锁定 +ThreadName=Thread-7获得锁定 +ThreadName=Thread-8获得锁定 + +---------------------------------- +★线程Thread-0运行了 +ThreadName=Thread-0获得锁定 +★线程Thread-2运行了 +ThreadName=Thread-2获得锁定 +★线程Thread-1运行了 +★线程Thread-3运行了 +★线程Thread-4运行了 +ThreadName=Thread-1获得锁定 +★线程Thread-5运行了 +ThreadName=Thread-5获得锁定 +★线程Thread-9运行了 +ThreadName=Thread-9获得锁定 +★线程Thread-8运行了 +ThreadName=Thread-8获得锁定 +★线程Thread-6运行了 +ThreadName=Thread-6获得锁定 +ThreadName=Thread-3获得锁定 +★线程Thread-7运行了 +ThreadName=Thread-7获得锁定 +ThreadName=Thread-4获得锁定 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Service.java new file mode 100644 index 0000000..e7a57ce --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example4/Service.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.lock.example4; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service { + private ReentrantLock lock; + + public Service(boolean isFair) { + this.lock = new ReentrantLock(isFair); + } + + public void serviceMethod() { + try { + lock.lock(); + System.out.println("ThreadName=" + Thread.currentThread().getName() + "获得锁定"); + } finally { + lock.unlock(); + } + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getHoldCount.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getHoldCount.java new file mode 100644 index 0000000..8415334 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getHoldCount.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.lock.example5; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P219 + * 测试方法int getHoldCount() + * 查询当前线程保持此锁定的个数,即调用lock()方法的次数 + */ +public class Run5_getHoldCount { + public static void main(String[] args) { + Service1 service = new Service1(); + service.serviceMethod1(); + } +} + + +/* +输出: +serviceMethod1 getHoldCount=1 +serviceMethod2 getHoldCount=2 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getQueueLength.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getQueueLength.java new file mode 100644 index 0000000..f6f90a3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getQueueLength.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.lock.example5; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P220 + * 测试方法int getQueueLength() + * 返回正在等待获取此锁定的线程估计数 + */ +public class Run5_getQueueLength { + public static void main(String[] args) throws InterruptedException { + final Service2 service = new Service2(); + Runnable runnable = new Runnable() { + public void run() { + service.serviceMethod1(); + } + }; + + Thread[] threads = new Thread[10]; + + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(runnable); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + + Thread.sleep(2000); + + System.out.println("有线程数:" + service.lock.getQueueLength() + "在等待获取锁"); + + } +} + + +/* +输出: +ThreadName=Thread-0 +有线程数:9在等待获取锁 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getWaitQueueLength.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getWaitQueueLength.java new file mode 100644 index 0000000..4884170 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Run5_getWaitQueueLength.java @@ -0,0 +1,53 @@ +package com.brianway.learning.java.multithread.lock.example5; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P221 + * 测试方法int getWaitQueueLength(Condition condition) + * 返回等待与此锁定相关的给定条件Condition的线程估计数 + */ +public class Run5_getWaitQueueLength { + public static void main(String[] args) throws InterruptedException { + final Service3 service = new Service3(); + Runnable runnable = new Runnable() { + public void run() { + service.waitMethod(); + } + }; + + Thread[] threads = new Thread[10]; + + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(runnable); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + + Thread.sleep(2000); + + service.notifyMethod(); + } +} + + +/* +输出: + +before await Thread-0 +before await Thread-5 +before await Thread-3 +before await Thread-8 +before await Thread-1 +before await Thread-2 +before await Thread-4 +before await Thread-6 +before await Thread-7 +before await Thread-9 +有10个线程正在等待newCondition +after await Thread-0 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service1.java new file mode 100644 index 0000000..ad1f9bd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service1.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.lock.example5; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service1 { + private ReentrantLock lock = new ReentrantLock(); + + public void serviceMethod1() { + try { + lock.lock(); + System.out.println("serviceMethod1 getHoldCount=" + lock.getHoldCount()); + serviceMethod2(); + } finally { + lock.unlock(); + } + } + + public void serviceMethod2() { + try { + lock.lock(); + System.out.println("serviceMethod2 getHoldCount=" + lock.getHoldCount()); + } finally { + lock.unlock(); + } + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service2.java new file mode 100644 index 0000000..2400073 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service2.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.lock.example5; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service2 { + public ReentrantLock lock = new ReentrantLock(); + + public void serviceMethod1() { + try { + lock.lock(); + System.out.println("ThreadName=" + Thread.currentThread().getName()); + Thread.sleep(Integer.MAX_VALUE); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service3.java new file mode 100644 index 0000000..06b5d0e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example5/Service3.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.multithread.lock.example5; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service3 { + private ReentrantLock lock = new ReentrantLock(); + private Condition newCondition = lock.newCondition(); + + public void waitMethod() { + try { + lock.lock(); + System.out.println("before await " + Thread.currentThread().getName()); + newCondition.await(); + System.out.println("after await " + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + public void notifyMethod() { + try { + lock.lock(); + System.out.println("有" + lock.getWaitQueueLength(newCondition) + "个线程正在等待newCondition"); + newCondition.signal(); + } finally { + lock.unlock(); + } + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasQueueThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasQueueThread.java new file mode 100644 index 0000000..6d77560 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasQueueThread.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.lock.example6; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P222 + * 测试方法boolean hasQueueThread(Thread thread) + * 查询指定的线程是否正在等待获取此锁定 + * 测试方法boolean hasQueueThreads() + * 查询是否有线程正在等待获取此锁定 + */ +public class Run6_hasQueueThread { + public static void main(String[] args) throws InterruptedException { + final Service1 service = new Service1(); + Runnable runnable = new Runnable() { + public void run() { + service.waitMethod(); + } + }; + + Thread threadA = new Thread(runnable); + threadA.start(); + Thread.sleep(500); + Thread threadB = new Thread(runnable); + threadB.start(); + Thread.sleep(500); + System.out.println(service.lock.hasQueuedThread(threadA)); + System.out.println(service.lock.hasQueuedThread(threadB)); + System.out.println(service.lock.hasQueuedThreads()); + } + +} + + +/* +输出: +false +true +true + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasWaiters.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasWaiters.java new file mode 100644 index 0000000..4b44416 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Run6_hasWaiters.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.lock.example6; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P223 + * 测试方法boolean hasWaiters(Condition) + * 查询是否有线程正在等待与此锁定有关的condition条件 + */ +public class Run6_hasWaiters { + public static void main(String[] args) throws InterruptedException { + final Service2 service = new Service2(); + Runnable runnable = new Runnable() { + public void run() { + service.waitMethod(); + } + }; + + Thread[] threads = new Thread[10]; + + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(runnable); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + + Thread.sleep(2000); + + service.notifyMethod(); + } +} + + +/* +输出: +有没有线程正在等待newCondition?true 线程数是多少?10 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Service1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Service1.java new file mode 100644 index 0000000..1d669fc --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Service1.java @@ -0,0 +1,23 @@ +package com.brianway.learning.java.multithread.lock.example6; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service1 { + public ReentrantLock lock = new ReentrantLock(); + public Condition newCondition = lock.newCondition(); + + public void waitMethod() { + try { + lock.lock(); + Thread.sleep(Integer.MAX_VALUE); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Service2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Service2.java new file mode 100644 index 0000000..61ec84d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example6/Service2.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.lock.example6; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service2 { + private ReentrantLock lock = new ReentrantLock(); + private Condition newCondition = lock.newCondition(); + + public void waitMethod() { + try { + lock.lock(); + //System.out.println("before await "+Thread.currentThread().getName()); + newCondition.await(); + //System.out.println("after await "+Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + public void notifyMethod() { + try { + lock.lock(); + System.out.println("有没有线程正在等待newCondition?" + lock.hasWaiters(newCondition) + " 线程数是多少?" + lock.getWaitQueueLength(newCondition)); + newCondition.signal(); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isFair.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isFair.java new file mode 100644 index 0000000..d4a9e90 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isFair.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.lock.example7; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P224 + * 测试方法boolean isFair() + * 判断是不是公平锁 + */ +public class Run7_isFair { + public static void main(String[] args) { + final Service1 service = new Service1(true); + Runnable runnable = new Runnable() { + public void run() { + service.serviceMethod(); + } + }; + Thread thread = new Thread(runnable); + thread.start(); + final Service1 service2 = new Service1(false); + runnable = new Runnable() { + public void run() { + service2.serviceMethod(); + } + }; + thread = new Thread(runnable); + thread.start(); + + } +} + +/* +输出: +公平锁情况:true +公平锁情况:false + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isHeldByCurrentThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isHeldByCurrentThread.java new file mode 100644 index 0000000..1e35786 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isHeldByCurrentThread.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.lock.example7; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P225 + * 测试方法boolean isHeldByCurrentThread() + * 查询当前线程是否保持此锁定 + */ +public class Run7_isHeldByCurrentThread { + public static void main(String[] args) { + final Service2 service = new Service2(true); + Runnable runnable = new Runnable() { + public void run() { + service.serviceMethod(); + } + }; + Thread thread = new Thread(runnable); + thread.start(); + } +} + + +/* +输出: +false +true + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isLocked.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isLocked.java new file mode 100644 index 0000000..d511eb7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Run7_isLocked.java @@ -0,0 +1,31 @@ +package com.brianway.learning.java.multithread.lock.example7; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P226 + * 测试方法boolean isLocked() + * 查询此锁定是否由任意线程保持 + */ +public class Run7_isLocked { + public static void main(String[] args) { + final Service3 service = new Service3(true); + Runnable runnable = new Runnable() { + public void run() { + service.serviceMethod(); + } + }; + + Thread thread = new Thread(runnable); + thread.start(); + } +} + + +/* +输出: +false +true + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service1.java new file mode 100644 index 0000000..d4687f7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service1.java @@ -0,0 +1,23 @@ +package com.brianway.learning.java.multithread.lock.example7; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service1 { + private ReentrantLock lock; + + public Service1(boolean isFair) { + lock = new ReentrantLock(isFair); + } + + public void serviceMethod() { + try { + lock.lock(); + System.out.println("公平锁情况:" + lock.isFair()); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service2.java new file mode 100644 index 0000000..960da34 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service2.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.lock.example7; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service2 { + private ReentrantLock lock; + + public Service2(boolean isFair) { + lock = new ReentrantLock(isFair); + } + + public void serviceMethod() { + try { + System.out.println(lock.isHeldByCurrentThread()); + lock.lock(); + System.out.println(lock.isHeldByCurrentThread()); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service3.java new file mode 100644 index 0000000..4db4486 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example7/Service3.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.lock.example7; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service3 { + private ReentrantLock lock; + + public Service3(boolean isFair) { + lock = new ReentrantLock(isFair); + } + + public void serviceMethod() { + try { + System.out.println(lock.isLocked()); + lock.lock(); + System.out.println(lock.isLocked()); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly1.java new file mode 100644 index 0000000..d656a6a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly1.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.lock.example8; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P227 + * 测试方法 void lockInterruptibly() + * 作用:如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常。 + */ +public class Run8_lockInterruptibly1 { + public static void main(String[] args) throws InterruptedException { + final Service1 service = new Service1(); + Runnable runnable = new Runnable() { + public void run() { + service.waitMethod(); + } + }; + + Thread threadA = new Thread(runnable); + threadA.setName("A"); + threadA.start(); + Thread.sleep(500); + Thread threadB = new Thread(runnable); + threadB.setName("B"); + threadB.start(); + threadB.interrupt(); + System.out.println("main end"); + + } +} + +/* +输出: +lock begin A +main end +lock end A +lock begin B +lock end B + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly2.java new file mode 100644 index 0000000..76552a9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_lockInterruptibly2.java @@ -0,0 +1,59 @@ +package com.brianway.learning.java.multithread.lock.example8; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P228 + * 测试方法 void lockInterruptibly() + * 作用:如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常。 + */ +public class Run8_lockInterruptibly2 { + public static void main(String[] args) throws InterruptedException { + final Service2 service = new Service2(); + Runnable runnable = new Runnable() { + public void run() { + service.waitMethod(); + } + }; + + Thread threadA = new Thread(runnable); + threadA.setName("A"); + threadA.start(); + Thread.sleep(500); + Thread threadB = new Thread(runnable); + threadB.setName("B"); + threadB.start(); + threadB.interrupt(); + System.out.println("main end"); + + } +} + +/* +输出: +lock begin A +java.lang.InterruptedException + at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220) + at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335) + at com.brianway.learning.java.multithread.lock.example8.Service2.waitMethod(Service2.java:15) + at com.brianway.learning.java.multithread.lock.example8.Run8_lockInterruptibly2$1.run(Run8_lockInterruptibly2.java:17) + at java.lang.Thread.run(Thread.java:745) +main end +lock end A + +----------------------------- + +lock begin A +main end +java.lang.InterruptedException + at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220) + at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335) + at com.brianway.learning.java.multithread.lock.example8.Service2.waitMethod(Service2.java:15) + at com.brianway.learning.java.multithread.lock.example8.Run8_lockInterruptibly2$1.run(Run8_lockInterruptibly2.java:17) + at java.lang.Thread.run(Thread.java:745) +lock end A + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock.java new file mode 100644 index 0000000..1d6cf87 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock.java @@ -0,0 +1,40 @@ +package com.brianway.learning.java.multithread.lock.example8; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P228 + * 测试方法boolean tryLock() + * 仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定 + */ +public class Run8_tryLock { + public static void main(String[] args) { + final Service3 service = new Service3(); + Runnable runnable = new Runnable() { + public void run() { + service.waitMethod(); + } + }; + + Thread threadA = new Thread(runnable); + threadA.setName("A"); + threadA.start(); + + Thread threadB = new Thread(runnable); + threadB.setName("B"); + threadB.start(); + } +} + +/* +输出: +B获得锁 +A没有获得锁 + +------------------ + +A获得锁 +B没有获得锁 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock_param.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock_param.java new file mode 100644 index 0000000..682be25 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Run8_tryLock_param.java @@ -0,0 +1,44 @@ +package com.brianway.learning.java.multithread.lock.example8; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P229 + * 测试方法boolean tryLock(long timeout,TimeUnit unit) + * 作用:如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定 + */ +public class Run8_tryLock_param { + public static void main(String[] args) { + final Service4 service = new Service4(); + Runnable runnable = new Runnable() { + public void run() { + System.out.println(Thread.currentThread().getName() + " 调用waitMethod时间:" + System.currentTimeMillis()); + service.waitMethod(); + } + }; + + Thread threadA = new Thread(runnable); + threadA.setName("A"); + threadA.start(); + + Thread threadB = new Thread(runnable); + threadB.setName("B"); + threadB.start(); + } +} + +/* +输出: +A 调用waitMethod时间:1460718796935 +B 调用waitMethod时间:1460718796935 +B获得锁的时间:1460718796936 +A没有获得锁 + +------------------------- +A 调用waitMethod时间:1460718824000 +B 调用waitMethod时间:1460718824000 +A获得锁的时间:1460718824000 +B没有获得锁 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service1.java new file mode 100644 index 0000000..1aac5b4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service1.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.lock.example8; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service1 { + public ReentrantLock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void waitMethod() { + try { + lock.lock(); + System.out.println("lock begin " + Thread.currentThread().getName()); + for (int i = 0; i < Integer.MAX_VALUE / 10; i++) { + String s = new String(); + Math.random(); + } + System.out.println("lock end " + Thread.currentThread().getName()); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service2.java new file mode 100644 index 0000000..975547a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service2.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.lock.example8; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service2 { + public ReentrantLock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void waitMethod() { + try { + lock.lockInterruptibly(); + System.out.println("lock begin " + Thread.currentThread().getName()); + for (int i = 0; i < Integer.MAX_VALUE / 10; i++) { + String s = new String(); + Math.random(); + } + System.out.println("lock end " + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service3.java new file mode 100644 index 0000000..640ecda --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service3.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.lock.example8; + +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service3 { + public ReentrantLock lock = new ReentrantLock(); + + public void waitMethod() { + if (lock.tryLock()) { + System.out.println(Thread.currentThread().getName() + "获得锁"); + } else { + System.out.println(Thread.currentThread().getName() + "没有获得锁"); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service4.java new file mode 100644 index 0000000..8f86ac1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example8/Service4.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.lock.example8; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service4 { + public ReentrantLock lock = new ReentrantLock(); + + public void waitMethod() { + try { + if (lock.tryLock(3, TimeUnit.SECONDS)) { + System.out.println(Thread.currentThread().getName() + "获得锁的时间:" + System.currentTimeMillis()); + Thread.sleep(10000); + } else { + System.out.println(Thread.currentThread().getName() + "没有获得锁"); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly1.java new file mode 100644 index 0000000..df00ad7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly1.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P230 + * 测试方法awaitUniterruptibly() + */ +public class Run9_awaitUniterruptibly1 { + public static void main(String[] args) { + try { + Service1 service = new Service1(); + Thread1 thread = new Thread1(service); + thread.start(); + Thread.sleep(3000); + thread.interrupt(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +wait begin +java.lang.InterruptedException + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2048) + at com.brianway.learning.java.multithread.lock.example9.Service1.testMethod(Service1.java:17) + at com.brianway.learning.java.multithread.lock.example9.Thread1.run(Thread1.java:15) +catch + +----------------------- + +wait begin +catch +java.lang.InterruptedException + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2048) + at com.brianway.learning.java.multithread.lock.example9.Service1.testMethod(Service1.java:17) + at com.brianway.learning.java.multithread.lock.example9.Thread1.run(Thread1.java:15) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly2.java new file mode 100644 index 0000000..587f1b8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUniterruptibly2.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P232 + * 测试方法awaitUniterruptibly() + */ +public class Run9_awaitUniterruptibly2 { + public static void main(String[] args) { + try { + Service2 service = new Service2(); + Thread2 thread = new Thread2(service); + thread.start(); + Thread.sleep(3000); + thread.interrupt(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +wait begin + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil1.java new file mode 100644 index 0000000..f6f2f43 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil1.java @@ -0,0 +1,25 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P233 + * 测试方法awaitUntil() + * 到达等待时间可唤醒自己 + */ +public class Run9_awaitUntil1 { + public static void main(String[] args) { + Service service = new Service(); + ThreadA threadA = new ThreadA(service); + threadA.start(); + } +} + + +/* +输出: +wait begin timer=1460724068711 +wait end timer=1460724078704 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil2.java new file mode 100644 index 0000000..072e930 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Run9_awaitUntil2.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P233 + * 测试方法awaitUntil() + * 线程在等待时间到达前,可以被其他线程唤醒 + */ +public class Run9_awaitUntil2 { + public static void main(String[] args) throws InterruptedException { + Service service = new Service(); + ThreadA threadA = new ThreadA(service); + threadA.start(); + Thread.sleep(2000); + ThreadB threadB = new ThreadB(service); + threadB.start(); + } +} + + +/* +输出: +wait begin timer=1460724153513 +notify begin timer=1460724155507 +notify end timer=1460724155507 +wait end timer=1460724155508 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service.java new file mode 100644 index 0000000..2c9e727 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.lock.example9; + +import java.util.Calendar; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service { + private ReentrantLock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void waitMethod() { + try { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 10); + lock.lock(); + System.out.println("wait begin timer=" + System.currentTimeMillis()); + condition.awaitUntil(calendar.getTime()); + System.out.println("wait end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + + public void notifyMethod() { + try { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 10); + lock.lock(); + System.out.println("notify begin timer=" + System.currentTimeMillis()); + condition.signalAll(); + System.out.println("notify end timer=" + System.currentTimeMillis()); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service1.java new file mode 100644 index 0000000..a962c23 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service1.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.lock.example9; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service1 { + private ReentrantLock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void testMethod() { + try { + lock.lock(); + System.out.println("wait begin"); + condition.await(); + System.out.println("wait end"); + } catch (InterruptedException e) { + e.printStackTrace(); + System.out.println("catch"); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service2.java new file mode 100644 index 0000000..3b1f18b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Service2.java @@ -0,0 +1,23 @@ +package com.brianway.learning.java.multithread.lock.example9; + +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Created by Brian on 2016/4/15. + */ +public class Service2 { + private ReentrantLock lock = new ReentrantLock(); + private Condition condition = lock.newCondition(); + + public void testMethod() { + try { + lock.lock(); + System.out.println("wait begin"); + condition.awaitUninterruptibly(); + System.out.println("wait end"); + } finally { + lock.unlock(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Thread1.java new file mode 100644 index 0000000..5e576a5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Thread1.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ +public class Thread1 extends Thread { + private Service1 service; + + public Thread1(Service1 service) { + this.service = service; + } + + @Override + public void run() { + service.testMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Thread2.java new file mode 100644 index 0000000..c76696b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/Thread2.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ +public class Thread2 extends Thread { + private Service2 service; + + public Thread2(Service2 service) { + this.service = service; + } + + @Override + public void run() { + service.testMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/ThreadA.java new file mode 100644 index 0000000..e4e0cf8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/ThreadA.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ +public class ThreadA extends Thread { + private Service service; + + public ThreadA(Service service) { + this.service = service; + } + + @Override + public void run() { + service.waitMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/ThreadB.java new file mode 100644 index 0000000..dc1c929 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/lock/example9/ThreadB.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.lock.example9; + +/** + * Created by Brian on 2016/4/15. + */ +public class ThreadB extends Thread { + private Service service; + + public ThreadB(Service service) { + this.service = service; + } + + @Override + public void run() { + service.notifyMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run.java new file mode 100644 index 0000000..10c4bbd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/10. + */ + +/** + * P11数据共享的例子 + */ + +class MyThread extends Thread { + private int count = 5; + + @Override + public void run() { + super.run(); + count--; + System.out.println("由" + this.currentThread().getName() + " 计算,count=" + count); + } +} + +public class Run { + public static void main(String[] args) { + MyThread myThread = new MyThread(); + Thread a = new Thread(myThread, "A"); + Thread b = new Thread(myThread, "B"); + Thread c = new Thread(myThread, "C"); + Thread d = new Thread(myThread, "D"); + a.start(); + b.start(); + c.start(); + d.start(); + } +} + + +/* +output(某一次): +由A 计算,count=3 +由C 计算,count=2 +由B 计算,count=3 +由D 计算,count=1 + +output(某一次): +由A 计算,count=4 +由C 计算,count=3 +由D 计算,count=1 +由B 计算,count=1 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run10_isInterrupted.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run10_isInterrupted.java new file mode 100644 index 0000000..588116c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run10_isInterrupted.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P26例子 + * isInterrupted(),不清除状态标记 + */ + +public class Run10_isInterrupted { + public static void main(String[] args) { + try { + MyThread7 myThread7 = new MyThread7(); + myThread7.start(); + Thread.sleep(100); + myThread7.interrupt(); + System.out.println("Thread.interrupted(),是否停止1?=" + myThread7.isInterrupted()); + System.out.println("Thread.interrupted(),是否停止2?=" + myThread7.isInterrupted()); + } catch (InterruptedException e) { + System.out.println("main catch"); + e.printStackTrace(); + } + System.out.println("end"); + } +} + +/* +输出节选: +i=17596 +i=17597 +i=17598 +i=17599 +Thread.interrupted(),是否停止1?=true +Thread.interrupted(),是否停止2?=true +end +i=17600 +i=17601 +i=17602 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run11_sleepAndinterrupt01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run11_sleepAndinterrupt01.java new file mode 100644 index 0000000..c1d8f2c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run11_sleepAndinterrupt01.java @@ -0,0 +1,60 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P30 + * 睡眠中停止,先进入的sleep,再interrupt() + */ +class MyThread11 extends Thread { + @Override + public void run() { + super.run(); + + try { + System.out.println("run begin"); + Thread.sleep(20000); + System.out.println("run end"); + } catch (InterruptedException e) { + System.out.println("沉睡中被停止!进入catch!" + this.isInterrupted()); + e.printStackTrace(); + } + } +} + +public class Run11_sleepAndinterrupt01 { + public static void main(String[] args) { + try { + MyThread11 myThread11 = new MyThread11(); + myThread11.start(); + Thread.sleep(200); + myThread11.interrupt(); + } catch (InterruptedException e) { + System.out.println("main catch"); + e.printStackTrace(); + } + System.out.println("end"); + } +} + +/* +输出: +run begin +沉睡中被停止!进入catch!false +end +java.lang.InterruptedException: sleep interrupted + at java.lang.Thread.sleep(Native Method) + at com.brianway.learning.java.multithread.meet.MyThread11.run(Run11_sleepAndinterrupt01.java:18) + +------- +输出不唯一: +run begin +end +沉睡中被停止!进入catch!false +java.lang.InterruptedException: sleep interrupted + at java.lang.Thread.sleep(Native Method) + at com.brianway.learning.java.multithread.meet.MyThread11.run(Run11_sleepAndinterrupt01.java:18) + +*/ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run12_sleepAndinterrupt02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run12_sleepAndinterrupt02.java new file mode 100644 index 0000000..f9efd94 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run12_sleepAndinterrupt02.java @@ -0,0 +1,58 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P31例子 + * 先interrupt(),再进入sleep(),直接进异常 + */ +class MyThread12 extends Thread { + @Override + public void run() { + super.run(); + try { + for (int i = 0; i < 100000; i++) { + System.out.println("i=" + (i + 1)); + } + System.out.println("run begin"); + Thread.sleep(200000); + System.out.println("run end"); + } catch (InterruptedException e) { + System.out.println("先停止,再遇到了sleep!进入catch"); + e.printStackTrace(); + } + } +} + +public class Run12_sleepAndinterrupt02 { + public static void main(String[] args) { + MyThread12 myThread12 = new MyThread12(); + myThread12.start(); + myThread12.interrupt(); + System.out.println("end!"); + } +} + +/* +输出: +end! +i=1 +i=2 +i=3 +i=4 +省略。。。 + +i=99998 +i=99999 +i=100000 +run begin +先停止,再遇到了sleep!进入catch +java.lang.InterruptedException: sleep interrupted + at java.lang.Thread.sleep(Native Method) + at com.brianway.learning.java.multithread.meet.MyThread12.run(Run12_sleepAndinterrupt02.java:19) + + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run13_suspendAndresume01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run13_suspendAndresume01.java new file mode 100644 index 0000000..604a8ee --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run13_suspendAndresume01.java @@ -0,0 +1,66 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P36例子 + * 暂停线程 + * suspend与resume + */ +class MyThread13 extends Thread { + private long i = 0; + + public long getI() { + return i; + } + + public void setI(long i) { + this.i = i; + } + + @Override + public void run() { + while (true) { + i++; + } + } +} + +public class Run13_suspendAndresume01 { + public static void main(String[] args) { + try { + MyThread13 myThread13 = new MyThread13(); + myThread13.start(); + Thread.sleep(5000); + //A段 + myThread13.suspend(); + System.out.println("A= " + System.currentTimeMillis() + " i=" + myThread13.getI()); + Thread.sleep(5000); + System.out.println("A= " + System.currentTimeMillis() + " i=" + myThread13.getI()); + + //B段 + myThread13.resume(); + Thread.sleep(5000); + //C段 + myThread13.suspend(); + System.out.println("B= " + System.currentTimeMillis() + " i=" + myThread13.getI()); + Thread.sleep(5000); + System.out.println("B= " + System.currentTimeMillis() + " i=" + myThread13.getI()); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("end"); + } +} + +/* +输出: +A= 1460358676950 i=2813771327 +A= 1460358681950 i=2813771327 +B= 1460358686951 i=5617784671 +B= 1460358691951 i=5617784671 +end + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run14_suspendAndresume02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run14_suspendAndresume02.java new file mode 100644 index 0000000..91bd703 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run14_suspendAndresume02.java @@ -0,0 +1,59 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P38例子 + * suspend与resume的缺点:独占 + */ + +class SynchronizedObject { + synchronized public void printString() { + System.out.println("begin printString"); + if (Thread.currentThread().getName().equals("a")) { + System.out.println("a线程永远suspend了!"); + Thread.currentThread().suspend(); + } + System.out.println("end printString"); + } +} + +public class Run14_suspendAndresume02 { + public static void main(String[] args) { + try { + final SynchronizedObject object = new SynchronizedObject(); + Thread thread1 = new Thread() { + @Override + public void run() { + object.printString(); + } + }; + thread1.setName("a"); + thread1.start(); + Thread.sleep(1000); + + Thread thread2 = new Thread() { + @Override + public void run() { + System.out.println("thread2启动了,但进不了printString()方法!只打印一个begin"); + System.out.println("因为printString()方法被a线程锁定并且永远suspend暂停了!"); + object.printString(); + } + }; + thread2.start(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +begin printString +a线程永远suspend了! +thread2启动了,但进不了printString()方法!只打印一个begin +因为printString()方法被a线程锁定并且永远suspend暂停了! + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run15_suspendAndresume03.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run15_suspendAndresume03.java new file mode 100644 index 0000000..4337be5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run15_suspendAndresume03.java @@ -0,0 +1,66 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P39 + * suspend独占锁问题,println() + */ + +class MyThread15 extends Thread { + private long i = 0; + + @Override + public void run() { + while (true) { + i++; + System.out.println(i); + } + } +} + +public class Run15_suspendAndresume03 { + public static void main(String[] args) { + try { + MyThread15 myThread15 = new MyThread15(); + myThread15.start(); + Thread.sleep(1000); + System.out.println("main before myThread15.suspend()!"); + myThread15.suspend(); + System.out.println("main end!"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +/* +输出: +09162 +309163 +main before myThread15.suspend()! +309164 +309165 +309166 +309167 +309168 +309169 +309170 +309171 +309172 +309173 +309174 +309175 +309176 +309177 +309178 +309179 +309180 +309181 +309182 +309183 + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run16_yield.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run16_yield.java new file mode 100644 index 0000000..e5da48a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run16_yield.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P42例子 + * 测试yield + */ + +class MyThread16 extends Thread { + @Override + public void run() { + long beginTime = System.currentTimeMillis(); + int count = 0; + for (int i = 0; i < 50000000; i++) { + Thread.yield(); + count = count + (i + 1); + } + long endTime = System.currentTimeMillis(); + System.out.println("用时:" + (endTime - beginTime) + "毫秒"); + } +} + +public class Run16_yield { + public static void main(String[] args) { + MyThread16 myThread16 = new MyThread16(); + myThread16.start(); + } +} + + +/* +//Thread.yield(); +输出: +用时:2毫秒 + +----------------- + +Thread.yield(); +输出: +用时:3302毫秒 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run17_priority01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run17_priority01.java new file mode 100644 index 0000000..39672ad --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run17_priority01.java @@ -0,0 +1,56 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P43例子 + * 线程优先级的继承性 + */ + +class MyThread17_1 extends Thread { + @Override + public void run() { + System.out.println("MyThread17_1 run priority=" + this.getPriority()); + MyThread17_2 myThread17_2 = new MyThread17_2(); + myThread17_2.start(); + + } +} + +class MyThread17_2 extends Thread { + @Override + public void run() { + System.out.println("MyThread17_2 run priority=" + this.getPriority()); + } +} + +public class Run17_priority01 { + public static void main(String[] args) { + System.out.println("main thread begin priority =" + Thread.currentThread().getPriority()); + //Thread.currentThread().setPriority(6); + System.out.println("main thread end priority =" + Thread.currentThread().getPriority()); + MyThread17_1 myThread17_1 = new MyThread17_1(); + myThread17_1.start(); + } +} + +/* +//Thread.currentThread().setPriority(6); +输出: +main thread begin priority =5 +main thread end priority =5 +MyThread17_1 run priority=5 +MyThread17_2 run priority=5 + +-------------------- + +Thread.currentThread().setPriority(6); +输出: +main thread begin priority =5 +main thread end priority =6 +MyThread17_1 run priority=6 +MyThread17_2 run priority=6 + + */ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run18_priority02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run18_priority02.java new file mode 100644 index 0000000..5e73d3b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run18_priority02.java @@ -0,0 +1,123 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/11. + */ + +import java.util.Random; + +/** + * P45例子 + * 优先级具有规则性 + */ + +class MyThread18_1 extends Thread { + @Override + public void run() { + long beginTime = System.currentTimeMillis(); + long addResult = 0; + for (int j = 0; j < 10; j++) { + for (int i = 0; i < 50000; i++) { + Random random = new Random(); + random.nextInt(); + addResult += i; + } + } + long endTime = System.currentTimeMillis(); + System.out.println("★★★★★ thread1 use time = " + (endTime - beginTime)); + } +} + +class MyThread18_2 extends Thread { + @Override + public void run() { + long beginTime = System.currentTimeMillis(); + long addResult = 0; + for (int j = 0; j < 10; j++) { + for (int i = 0; i < 50000; i++) { + Random random = new Random(); + random.nextInt(); + addResult += i; + } + } + long endTime = System.currentTimeMillis(); + System.out.println("☆☆☆☆☆ thread2 use time = " + (endTime - beginTime)); + } +} + +public class Run18_priority02 { + public static void main(String[] args) { + for (int i = 0; i < 5; i++) { + MyThread18_1 myThread18_1 = new MyThread18_1(); + myThread18_1.setPriority(10); + //myThread18_1.setPriority(1); + myThread18_1.start(); + MyThread18_2 myThread18_2 = new MyThread18_2(); + //myThread18_2.setPriority(10); + myThread18_2.setPriority(1); + myThread18_2.start(); + } + } +} + + +/* +myThread18_1.setPriority(10); +myThread18_2.setPriority(1); +输出: +☆☆☆☆☆ thread2 use time = 202 +★★★★★ thread1 use time = 208 +★★★★★ thread1 use time = 255 +★★★★★ thread1 use time = 261 +★★★★★ thread1 use time = 268 +★★★★★ thread1 use time = 270 +☆☆☆☆☆ thread2 use time = 321 +☆☆☆☆☆ thread2 use time = 338 +☆☆☆☆☆ thread2 use time = 344 +☆☆☆☆☆ thread2 use time = 35 + +------------------------- + +★★★★★ thread1 use time = 121 +★★★★★ thread1 use time = 232 +☆☆☆☆☆ thread2 use time = 268 +☆☆☆☆☆ thread2 use time = 292 +★★★★★ thread1 use time = 322 +☆☆☆☆☆ thread2 use time = 325 +★★★★★ thread1 use time = 387 +☆☆☆☆☆ thread2 use time = 390 +★★★★★ thread1 use time = 395 +☆☆☆☆☆ thread2 use time = 409 + + +---------------------------------------------------- +---------------------------------------------------- +myThread18_1.setPriority(1); +myThread18_2.setPriority(10); +输出: + +☆☆☆☆☆ thread2 use time = 393 +☆☆☆☆☆ thread2 use time = 455 +☆☆☆☆☆ thread2 use time = 496 +☆☆☆☆☆ thread2 use time = 509 +☆☆☆☆☆ thread2 use time = 510 +★★★★★ thread1 use time = 511 +★★★★★ thread1 use time = 554 +★★★★★ thread1 use time = 558 +★★★★★ thread1 use time = 561 +★★★★★ thread1 use time = 569 + +--------------- + +☆☆☆☆☆ thread2 use time = 214 +☆☆☆☆☆ thread2 use time = 230 +☆☆☆☆☆ thread2 use time = 237 +★★★★★ thread1 use time = 257 +☆☆☆☆☆ thread2 use time = 261 +☆☆☆☆☆ thread2 use time = 271 +★★★★★ thread1 use time = 350 +★★★★★ thread1 use time = 369 +★★★★★ thread1 use time = 339 +★★★★★ thread1 use time = 382 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run2_StartVsRun.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run2_StartVsRun.java new file mode 100644 index 0000000..20722d1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run2_StartVsRun.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P16小例子 + * myThread2.start()和myThread2.run()的区别 + */ + +class MyThread2 extends Thread { + public MyThread2() { + System.out.println("构造方法打印:" + Thread.currentThread().getName()); + } + + @Override + public void run() { + System.out.println("run方法打印:" + Thread.currentThread().getName()); + } +} + +public class Run2_StartVsRun { + public static void main(String[] args) { + MyThread2 myThread2 = new MyThread2(); + myThread2.start(); + //myThread2.run(); + } +} + + + +/* + myThread2.start(); +//myThread2.run(); +输出: +构造方法打印:main +run方法打印:Thread-0 + +-------------------- +//myThread2.start(); +myThread2.run(); +输出: +构造方法打印:main +run方法打印:main + +*/ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run3_getName.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run3_getName.java new file mode 100644 index 0000000..5d33583 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run3_getName.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P17小例子 + * this.getName()!=Thread.currentThread().getName(),这是两个概念。 + */ +class CountOperate extends Thread { + public CountOperate() { + System.out.println("CountOperate---begin"); + System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); + System.out.println("this.getName()=" + this.getName()); + System.out.println("CountOperate---end"); + } + + @Override + public void run() { + System.out.println("run---begin"); + System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); + System.out.println("this.getName()=" + this.getName()); + System.out.println("run---end"); + } +} + +public class Run3_getName { + public static void main(String[] args) { + CountOperate c = new CountOperate(); + Thread t1 = new Thread(c); + t1.setName("A"); + t1.start(); + } +} + +/* +输出: +CountOperate---begin +Thread.currentThread().getName()=main +this.getName()=Thread-0 +CountOperate---end +run---begin +Thread.currentThread().getName()=A +this.getName()=Thread-0 +run---end + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run4_isAlive01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run4_isAlive01.java new file mode 100644 index 0000000..1eeb7de --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run4_isAlive01.java @@ -0,0 +1,44 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P18 + * isAlive() + */ +class MyThread4 extends Thread { + @Override + public void run() { + System.out.println("run=" + this.isAlive()); + } +} + +public class Run4_isAlive01 { + public static void main(String[] args) throws InterruptedException { + MyThread4 myThread4 = new MyThread4(); + System.out.println("begin == " + myThread4.isAlive()); + myThread4.start(); + //Thread.sleep(1000); + System.out.println("end == " + myThread4.isAlive()); + } + +} + +/* +输出: +begin == false +end == true +run=true + +-------------- +Thread.sleep(1000); + +输出: +begin == false +run=true +end == false + +*/ + diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run5_isAlive02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run5_isAlive02.java new file mode 100644 index 0000000..0b0bcf5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run5_isAlive02.java @@ -0,0 +1,60 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P19 小例子 + * isAlive()方法测试 + */ +class CountOperate2 extends Thread { + public CountOperate2() { + System.out.println("CountOperate---begin"); + System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); + System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); + System.out.println("this.getName()=" + this.getName()); + System.out.println("this.isAlive()=" + this.isAlive()); + System.out.println("CountOperate---end"); + } + + @Override + public void run() { + System.out.println("run---begin"); + System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName()); + System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive()); + System.out.println("this.getName()=" + this.getName()); + System.out.println("this.isAlive()=" + this.isAlive()); + System.out.println("run---end"); + } +} + +public class Run5_isAlive02 { + public static void main(String[] args) { + CountOperate2 c = new CountOperate2(); + Thread t1 = new Thread(c); + System.out.println("main begin t1 isAlive=" + t1.isAlive()); + t1.setName("A"); + t1.start(); + System.out.println("main end t1 isAlive=" + t1.isAlive()); + } +} + +/* +输出: +CountOperate---begin +Thread.currentThread().getName()=main +Thread.currentThread().isAlive()=true +this.getName()=Thread-0 +this.isAlive()=false +CountOperate---end +main begin t1 isAlive=false +main end t1 isAlive=true +run---begin +Thread.currentThread().getName()=A +Thread.currentThread().isAlive()=true +this.getName()=Thread-0 +this.isAlive()=false +run---end + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run6_StartVsRun02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run6_StartVsRun02.java new file mode 100644 index 0000000..e97c88c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run6_StartVsRun02.java @@ -0,0 +1,56 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P20~21 + * sleep()方法测试 + * run---同步执行 + * start---异步执行 + * 所以输出顺序有所不同 + */ +class MyThread6 extends Thread { + @Override + public void run() { + try { + System.out.println("run threadName=" + this.currentThread().getName() + " begin"); + Thread.sleep(2000); + System.out.println("run threadName=" + this.currentThread().getName() + " end"); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + +public class Run6_StartVsRun02 { + public static void main(String[] args) { + MyThread6 myThread6 = new MyThread6(); + System.out.println("begin = " + System.currentTimeMillis()); + //myThread6.run(); + myThread6.start(); + System.out.println("end = " + System.currentTimeMillis()); + } +} + +/* +myThread6.run(); +//myThread6.start(); +输出: +begin = 1460340883191 +run threadName=main begin +run threadName=main end +end = 1460340885192 + +----------------------- +//myThread6.run(); +myThread6.start(); +输出: +begin = 1460341011862 +end = 1460341011862 +run threadName=Thread-0 begin +run threadName=Thread-0 end + +*/ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run7_interrupt01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run7_interrupt01.java new file mode 100644 index 0000000..04a81c2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run7_interrupt01.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P23 + * 停止线程 + */ + +class MyThread7 extends Thread { + @Override + public void run() { + super.run(); + for (int i = 0; i < 500000; i++) { + System.out.println("i=" + (i + 1)); + } + } +} + +public class Run7_interrupt01 { + public static void main(String[] args) { + try { + MyThread7 myThread7 = new MyThread7(); + myThread7.start(); + Thread.sleep(1000); + myThread7.interrupt(); + } catch (InterruptedException e) { + System.out.println("main catch"); + e.printStackTrace(); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run8_interrupted01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run8_interrupted01.java new file mode 100644 index 0000000..7fca303 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run8_interrupted01.java @@ -0,0 +1,68 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P25 + * 判断线程是否停止状态 + * 测试当前线程是否已经中断 + */ +class MyThread8 extends Thread { + @Override + public void run() { + super.run(); + for (int i = 0; i < 500; i++) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("i=" + (i + 1)); + } + } +} + +public class Run8_interrupted01 { + public static void main(String[] args) { + try { + MyThread8 myThread8 = new MyThread8(); + myThread8.start(); + Thread.sleep(1000); + myThread8.interrupt(); + System.out.println("Thread.interrupted(),是否停止1?=" + Thread.interrupted()); + System.out.println("Thread.interrupted(),是否停止2?=" + Thread.interrupted()); + } catch (InterruptedException e) { + System.out.println("main catch"); + e.printStackTrace(); + } + System.out.println("end"); + } +} + +/* +输出: +i=1 +i=2 +i=3 +i=4 +i=5 +i=6 +i=7 +i=8 +i=9 +java.lang.InterruptedException: sleep interrupted + at java.lang.Thread.sleep(Native Method) + at com.brianway.learning.java.multithread.meet.MyThread8.run(Run8_interrupted01.java:18) +Thread.interrupted(),是否停止1?=false +Thread.interrupted(),是否停止2?=false +end +i=10 +i=11 +省略.... + +----------------- + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run9_interrupted02.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run9_interrupted02.java new file mode 100644 index 0000000..c922574 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/Run9_interrupted02.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by brian on 2016/4/11. + */ + +/** + * P26例子 + * 线程的中断状态由interrupted()清除 + */ +public class Run9_interrupted02 { + public static void main(String[] args) { + Thread.currentThread().interrupt(); + System.out.println("Thread.interrupted(),是否停止1?=" + Thread.interrupted()); + System.out.println("Thread.interrupted(),是否停止2?=" + Thread.interrupted()); + System.out.println("end"); + } +} + +/* +输出: +Thread.interrupted(),是否停止1?=true +Thread.interrupted(),是否停止2?=false +end + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/printMain.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/printMain.java new file mode 100644 index 0000000..6bb4b44 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/meet/printMain.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.meet; + +/** + * Created by Brian on 2016/4/10. + */ + +/** + * P4的小例子 + */ +public class printMain { + public static void main(String[] args) { + System.out.println(Thread.currentThread().getName()); + } +} + +/* +output: +main + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject0.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject0.java new file mode 100644 index 0000000..6bcbac4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject0.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * 缺点:不能有其他实例变量 + * getInstance()方法没有同步,可能出现非线程安全问题 + */ +public class MyObject0 { + private static MyObject0 myObject = new MyObject0(); + + private MyObject0() { + } + + public static MyObject0 getInstance() { + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject1.java new file mode 100644 index 0000000..6725898 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject1.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject1 { + private static MyObject1 myObject; + + private MyObject1() { + } + + public static MyObject1 getInstance() { + //延迟加载 + if (myObject == null) { + myObject = new MyObject1(); + } + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject2.java new file mode 100644 index 0000000..7251bb7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/MyObject2.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject2 { + private static MyObject2 myObject; + + private MyObject2() { + } + + public static MyObject2 getInstance() { + + try { + if (myObject == null) { + Thread.sleep(2000);//模拟创建对象前的坐一些准备 + myObject = new MyObject2(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton0.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton0.java new file mode 100644 index 0000000..0b7f3e3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton0.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p262 + * 立即加载/“饿汉模式” + */ +public class Run1_singleton0 { + public static void main(String[] args) { + Thread0 t1 = new Thread0(); + Thread0 t2 = new Thread0(); + Thread0 t3 = new Thread0(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +663838472 com.brianway.learning.java.multithread.singleton.example1.MyObject0@27915f08 +663838472 com.brianway.learning.java.multithread.singleton.example1.MyObject0@27915f08 +663838472 com.brianway.learning.java.multithread.singleton.example1.MyObject0@27915f08 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton1.java new file mode 100644 index 0000000..af9fdd1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton1.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p264 + * 延迟加载/“懒汉模式” + * 会出问题 + */ +public class Run1_singleton1 { + public static void main(String[] args) { + Thread1 t1 = new Thread1(); + Thread1 t2 = new Thread1(); + Thread1 t3 = new Thread1(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +541962297 com.brianway.learning.java.multithread.singleton.example1.MyObject1@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject1@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject1@3a1a7da6 + +--------------------------- + +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject1@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject1@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject1@3a1a7da6 + +-------------------------- + +1802892302 com.brianway.learning.java.multithread.singleton.example1.MyObject1@6b75f40e +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject1@6b75f40e +1771081048 com.brianway.learning.java.multithread.singleton.example1.MyObject1@6b75f40e + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton2.java new file mode 100644 index 0000000..1a54dc4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Run1_singleton2.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p265 + * 延迟加载/“懒汉模式”缺点展示 + */ +public class Run1_singleton2 { + public static void main(String[] args) { + Thread2 t1 = new Thread2(); + Thread2 t2 = new Thread2(); + Thread2 t3 = new Thread2(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +1771081048 com.brianway.learning.java.multithread.singleton.example1.MyObject2@6b75f40e +1802892302 com.brianway.learning.java.multithread.singleton.example1.MyObject2@6b75f40e +974814630 com.brianway.learning.java.multithread.singleton.example1.MyObject2@6b75f40e + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread0.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread0.java new file mode 100644 index 0000000..40e111a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread0.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread0 extends Thread { + @Override + public void run() { + System.out.println(MyObject0.getInstance().hashCode() + " " + MyObject0.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread1.java new file mode 100644 index 0000000..356263b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread1.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread1 extends Thread { + @Override + public void run() { + System.out.println(MyObject1.getInstance().hashCode() + " " + MyObject1.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread2.java new file mode 100644 index 0000000..452bd5a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example1/Thread2.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example1; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread2 extends Thread { + @Override + public void run() { + System.out.println(MyObject2.getInstance().hashCode() + " " + MyObject2.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject1.java new file mode 100644 index 0000000..a25344e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject1.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject1 { + private static MyObject1 myObject; + + private MyObject1() { + } + + synchronized public static MyObject1 getInstance() { + + try { + if (myObject == null) { + Thread.sleep(3000);//模拟创建对象前的坐一些准备 + myObject = new MyObject1(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject2.java new file mode 100644 index 0000000..7aa37c0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject2.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject2 { + private static MyObject2 myObject; + + private MyObject2() { + } + + public static MyObject2 getInstance() { + + try { + //此写法和方法前加synchronized一样效率低下,全部代码被上锁 + synchronized (MyObject2.class) { + if (myObject == null) { + Thread.sleep(3000);//模拟创建对象前的坐一些准备 + myObject = new MyObject2(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject3.java new file mode 100644 index 0000000..f3686e1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject3.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject3 { + private static MyObject3 myObject; + + private MyObject3() { + } + + public static MyObject3 getInstance() { + + try { + if (myObject == null) { + Thread.sleep(3000);//模拟创建对象前的坐一些准备 + //虽然部分代码被上锁,但还是有非线程安全问题 + synchronized (MyObject3.class) { + myObject = new MyObject3(); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject4.java new file mode 100644 index 0000000..51032be --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/MyObject4.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject4 { + private static MyObject4 myObject; + + private MyObject4() { + } + + public static MyObject4 getInstance() { + //双检查锁机制 + try { + if (myObject == null) { + Thread.sleep(3000);//模拟创建对象前的坐一些准备 + synchronized (MyObject4.class) { + if (myObject == null) { + myObject = new MyObject4(); + } + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + return myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton1.java new file mode 100644 index 0000000..e16611d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton1.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p266 + * 延迟加载/“懒汉模式”解决方案 + * 声明synchronized关键字,整个方法上锁 + * 效率低下,下一个线程想取得对象,须等上一个线程释放锁 + */ +public class Run2_singleton1 { + public static void main(String[] args) { + Thread1 t1 = new Thread1(); + Thread1 t2 = new Thread1(); + Thread1 t3 = new Thread1(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +872395065 com.brianway.learning.java.multithread.singleton.example2.MyObject1@33ffb139 +872395065 com.brianway.learning.java.multithread.singleton.example2.MyObject1@33ffb139 +872395065 com.brianway.learning.java.multithread.singleton.example2.MyObject1@33ffb139 + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton2.java new file mode 100644 index 0000000..6bfc98f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton2.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p267 + * 延迟加载/“懒汉模式”解决方案 + * 声明synchronized关键字,同步代码块 + * 效率低下 + */ +public class Run2_singleton2 { + public static void main(String[] args) { + Thread2 t1 = new Thread2(); + Thread2 t2 = new Thread2(); + Thread2 t3 = new Thread2(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +974814630 com.brianway.learning.java.multithread.singleton.example2.MyObject2@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example2.MyObject2@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example2.MyObject2@3a1a7da6 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton3.java new file mode 100644 index 0000000..67136fc --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton3.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p269 + * 延迟加载/“懒汉模式”解决方案 + * 声明synchronized关键字,部分代码上锁 + * 会出问题 + */ +public class Run2_singleton3 { + public static void main(String[] args) { + Thread3 t1 = new Thread3(); + Thread3 t2 = new Thread3(); + Thread3 t3 = new Thread3(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +541962297 com.brianway.learning.java.multithread.singleton.example2.MyObject3@3b162ba +974814630 com.brianway.learning.java.multithread.singleton.example2.MyObject3@3b162ba +61956794 com.brianway.learning.java.multithread.singleton.example2.MyObject3@3b162ba + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton4.java new file mode 100644 index 0000000..f77079d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Run2_singleton4.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p270 + * 延迟加载/“懒汉模式”解决方案 + * DCL双检查锁机制 + */ +public class Run2_singleton4 { + public static void main(String[] args) { + Thread4 t1 = new Thread4(); + Thread4 t2 = new Thread4(); + Thread4 t3 = new Thread4(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +2110701623 com.brianway.learning.java.multithread.singleton.example2.MyObject4@7dcec037 +2110701623 com.brianway.learning.java.multithread.singleton.example2.MyObject4@7dcec037 +2110701623 com.brianway.learning.java.multithread.singleton.example2.MyObject4@7dcec037 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread1.java new file mode 100644 index 0000000..7abe0a2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread1.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread1 extends Thread { + @Override + public void run() { + System.out.println(MyObject1.getInstance().hashCode() + " " + MyObject1.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread2.java new file mode 100644 index 0000000..7c6a256 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread2.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread2 extends Thread { + @Override + public void run() { + System.out.println(MyObject2.getInstance().hashCode() + " " + MyObject2.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread3.java new file mode 100644 index 0000000..74a55ad --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread3.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread3 extends Thread { + @Override + public void run() { + System.out.println(MyObject3.getInstance().hashCode() + " " + MyObject3.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread4.java new file mode 100644 index 0000000..c12a9c9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example2/Thread4.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example2; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread4 extends Thread { + @Override + public void run() { + System.out.println(MyObject4.getInstance().hashCode() + " " + MyObject4.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject1.java new file mode 100644 index 0000000..9708819 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject1.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject1 { + private static class MyObjectHandler { + private static MyObject1 myObject = new MyObject1(); + } + + private MyObject1() { + } + + synchronized public static MyObject1 getInstance() { + return MyObjectHandler.myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject2.java new file mode 100644 index 0000000..82610a8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject2.java @@ -0,0 +1,24 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +import java.io.Serializable; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject2 implements Serializable { + private static class MyObjectHandler { + private static final MyObject2 myObject = new MyObject2(); + } + + private MyObject2() { + } + + synchronized public static MyObject2 getInstance() { + return MyObjectHandler.myObject; + } + + protected Object readResolve() { + System.out.println("调用了readResolve方法"); + return MyObjectHandler.myObject; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject3.java new file mode 100644 index 0000000..0829a30 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject3.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject3 { + + private static MyObject3 instance = null; + + private MyObject3() { + } + + static { + instance = new MyObject3(); + } + + public static MyObject3 getInstance() { + return instance; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject4.java new file mode 100644 index 0000000..e52ed96 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject4.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public enum MyObject4 { + ObjectFactory; + private Object object; + + private MyObject4() { + try { + Thread.sleep(3000);//模拟初始化 + object = new Object(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public Object getObject() { + return object; + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject5.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject5.java new file mode 100644 index 0000000..d731d88 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/MyObject5.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class MyObject5 { + public enum MyEnumSingleton { + ObjectFactory; + private Object object; + + private MyEnumSingleton() { + try { + Thread.sleep(3000);//模拟初始化 + object = new Object(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public Object getObject() { + return object; + } + } + + public static Object getObject() { + return MyEnumSingleton.ObjectFactory.getObject(); + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton1.java new file mode 100644 index 0000000..c226366 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton1.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p272 + * 使用静态内置类实现单例模式 + */ +public class Run3_singleton1 { + public static void main(String[] args) { + Thread1 t1 = new Thread1(); + Thread1 t2 = new Thread1(); + Thread1 t3 = new Thread1(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +418579292 com.brianway.learning.java.multithread.singleton.example3.MyObject1@18f3035c +418579292 com.brianway.learning.java.multithread.singleton.example3.MyObject1@18f3035c +418579292 com.brianway.learning.java.multithread.singleton.example3.MyObject1@18f3035c + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton2.java new file mode 100644 index 0000000..d2c58dd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton2.java @@ -0,0 +1,65 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * p273 + * 序列化与反序列化的单例模式实现 + */ +public class Run3_singleton2 { + public static void main(String[] args) { + try { + MyObject2 myObject = MyObject2.getInstance(); + FileOutputStream fos = new FileOutputStream(new File("myObject.txt")); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(myObject); + oos.close(); + fos.close(); + System.out.println(myObject.hashCode() + " " + myObject); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + FileInputStream fis = new FileInputStream(new File("myObject.txt")); + ObjectInputStream ios = new ObjectInputStream(fis); + MyObject2 myObject = (MyObject2) ios.readObject(); + ios.close(); + fis.close(); + System.out.println(myObject.hashCode() + " " + myObject); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } +} + + +/* +输出: +325040804 com.brianway.learning.java.multithread.singleton.example3.MyObject2@135fbaa4 +1173230247 com.brianway.learning.java.multithread.singleton.example3.MyObject2@45ee12a7 + +------------------------ +取消MyObject2中protected Object readResolve()的注释 +输出: +325040804 com.brianway.learning.java.multithread.singleton.example3.MyObject2@135fbaa4 +调用了readResolve方法 +325040804 com.brianway.learning.java.multithread.singleton.example3.MyObject2@135fbaa4 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton3.java new file mode 100644 index 0000000..29d70cb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton3.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p275 + * 使用static代码块实现单例模式 + */ +public class Run3_singleton3 { + public static void main(String[] args) { + Thread3 t1 = new Thread3(); + Thread3 t2 = new Thread3(); + Thread3 t3 = new Thread3(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 +974814630 com.brianway.learning.java.multithread.singleton.example3.MyObject3@3a1a7da6 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton4.java new file mode 100644 index 0000000..cbe02ea --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton4.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p276 + * 使用enum枚举数据类型实现单例模式 + */ +public class Run3_singleton4 { + public static void main(String[] args) { + Thread4 t1 = new Thread4(); + Thread4 t2 = new Thread4(); + Thread4 t3 = new Thread4(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba +61956794 java.lang.Object@3b162ba + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton5.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton5.java new file mode 100644 index 0000000..79105a5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Run3_singleton5.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ + +/** + * p277 + * 使用enum枚举数据类型实现单例模式 + * 完善 + */ +public class Run3_singleton5 { + public static void main(String[] args) { + Thread5 t1 = new Thread5(); + Thread5 t2 = new Thread5(); + Thread5 t3 = new Thread5(); + t1.start(); + t2.start(); + t3.start(); + } +} + + +/* +输出: +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 +541962297 java.lang.Object@204db039 + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread1.java new file mode 100644 index 0000000..c2e3c0b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread1.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread1 extends Thread { + @Override + public void run() { + System.out.println(MyObject1.getInstance().hashCode() + " " + MyObject1.getInstance()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread3.java new file mode 100644 index 0000000..5e663e4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread3.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread3 extends Thread { + @Override + public void run() { + for (int i = 0; i < 5; i++) { + System.out.println(MyObject3.getInstance().hashCode() + " " + MyObject3.getInstance()); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread4.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread4.java new file mode 100644 index 0000000..a5e1a02 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread4.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread4 extends Thread { + @Override + public void run() { + for (int i = 0; i < 5; i++) { + System.out.println(MyObject4.ObjectFactory.getObject().hashCode() + " " + MyObject4.ObjectFactory.getObject()); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread5.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread5.java new file mode 100644 index 0000000..e8c55df --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/singleton/example3/Thread5.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.singleton.example3; + +/** + * Created by Brian on 2016/4/16. + */ +public class Thread5 extends Thread { + @Override + public void run() { + for (int i = 0; i < 5; i++) { + System.out.println(MyObject5.getObject().hashCode() + " " + MyObject5.getObject()); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/MyService.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/MyService.java new file mode 100644 index 0000000..1ccfb18 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/MyService.java @@ -0,0 +1,15 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ +public class MyService { + synchronized static public void serviveMethod() { + try { + System.out.println(Thread.currentThread().getName() + " 进入了业务方法"); + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state1.java new file mode 100644 index 0000000..00473cb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state1.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P280 + * 验证NEW,RUNNABLE,TERMINATED + */ +public class Run1_state1 { + public static void main(String[] args) { + try { + Thread1 t = new Thread1(); + System.out.println("main方法中的状态1:" + t.getState() + " of " + t.getName()); + Thread.sleep(1000); + t.start(); + Thread.sleep(1000); + System.out.println("main方法中的状态2:" + t.getState() + " of " + t.getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + + +/* +输出: +构造方法中的状态:NEW of Thread-0 +构造方法中的状态:RUNNABLE of main +main方法中的状态1:NEW of Thread-0 +run方法中的状态:RUNNABLE of Thread-0 +run方法中的状态:RUNNABLE of Thread-0 +main方法中的状态2:TERMINATED of Thread-0 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state2.java new file mode 100644 index 0000000..04ec555 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state2.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P282 + * 验证TIMED_WAITING + */ +public class Run1_state2 { + public static void main(String[] args) { + try { + Thread2 t = new Thread2(); + t.start(); + Thread.sleep(1000); + System.out.println("main方法中的状态:" + t.getState() + " of " + t.getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + + +/* +输出: +begin sleep,run方法中的状态:RUNNABLE of Thread-0 +begin sleep,run方法中的状态:RUNNABLE of Thread-0 +main方法中的状态:TIMED_WAITING of Thread-0 +end sleep,run方法中的状态:RUNNABLE of Thread-0 +end sleep,run方法中的状态:RUNNABLE of Thread-0 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state3.java new file mode 100644 index 0000000..5e8ac4a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Run1_state3.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P283 + * 验证BLOCKED + */ +public class Run1_state3 { + public static void main(String[] args) { + try { + Thread3 t1 = new Thread3(); + t1.setName("a"); + t1.start(); + Thread3 t2 = new Thread3(); + t2.setName("b"); + t2.start(); + Thread.sleep(1000); + System.out.println("main方法中的t2状态:" + t2.getState()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} + + +/* +输出: +a 进入了业务方法 +main方法中的t2状态:BLOCKED +b 进入了业务方法 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread1.java new file mode 100644 index 0000000..f8880fb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread1.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread1 extends Thread { + public Thread1() { + System.out.println("构造方法中的状态:" + this.getState() + " of " + this.getName()); + System.out.println("构造方法中的状态:" + Thread.currentThread().getState() + " of " + Thread.currentThread().getName()); + } + + @Override + public void run() { + System.out.println("run方法中的状态:" + this.getState() + " of " + this.getName()); + System.out.println("run方法中的状态:" + Thread.currentThread().getState() + " of " + Thread.currentThread().getName()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread2.java new file mode 100644 index 0000000..a205f6d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread2.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread2 extends Thread { + + @Override + public void run() { + try { + System.out.println("begin sleep,run方法中的状态:" + this.getState() + " of " + this.getName()); + System.out.println("begin sleep,run方法中的状态:" + Thread.currentThread().getState() + " of " + Thread.currentThread().getName()); + Thread.sleep(10000); + System.out.println("end sleep,run方法中的状态:" + this.getState() + " of " + this.getName()); + System.out.println("end sleep,run方法中的状态:" + Thread.currentThread().getState() + " of " + Thread.currentThread().getName()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread3.java new file mode 100644 index 0000000..dc84b08 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example1/Thread3.java @@ -0,0 +1,12 @@ +package com.brianway.learning.java.multithread.supplement.example1; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread3 extends Thread { + + @Override + public void run() { + MyService.serviveMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/MyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/MyThread.java new file mode 100644 index 0000000..e02393a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/MyThread.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * 取消System.out.println的注释能看到更多细节 + */ +public class MyThread extends Thread { + private Object lock; + private String showChar; + private int showNumPosition; + private int printCount = 0;//统计打印了几个字母 + volatile private static int addNumber = 1; + + public MyThread(Object lock, String showChar, int showNumPosition) { + this.lock = lock; + this.showChar = showChar; + this.showNumPosition = showNumPosition; + } + + @Override + public void run() { + try { + synchronized (lock) { + //System.out.println("ThreadName="+ Thread.currentThread().getName()+" get the lock"); + while (true) { + if (addNumber % 3 == showNumPosition) { + System.out.println("ThreadName=" + Thread.currentThread().getName() + + " runCount = " + addNumber + " " + showChar); + lock.notifyAll(); + addNumber++; + printCount++; + if (printCount == 3) { + break; + } + } else { + //System.out.println("ThreadName="+ Thread.currentThread().getName()+" will await"); + lock.wait(); + //System.out.println("ThreadName="+ Thread.currentThread().getName()+" after await"); + } + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_autoAddGroup.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_autoAddGroup.java new file mode 100644 index 0000000..81e9610 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_autoAddGroup.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * 线程组自动归属特性 + */ +public class Run2_autoAddGroup { + public static void main(String[] args) { + System.out.println("A处线程:" + Thread.currentThread().getName() + + " 所属的线程组名为:" + Thread.currentThread().getThreadGroup().getName() + + " 中有线程组数量:" + Thread.currentThread().getThreadGroup().activeGroupCount()); + + ThreadGroup group = new ThreadGroup("新的组"); + + System.out.println("A处线程:" + Thread.currentThread().getName() + + " 所属的线程组名为:" + Thread.currentThread().getThreadGroup().getName() + + " 中有线程组数量:" + Thread.currentThread().getThreadGroup().activeGroupCount()); + + ThreadGroup[] threadGroup = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()]; + Thread.currentThread().getThreadGroup().enumerate(threadGroup); + for (int i = 0; i < threadGroup.length; i++) { + System.out.println("第一个线程组名称为:" + threadGroup[i].getName()); + } + + } +} + +/* +输出: +A处线程:main 所属的线程组名为:main 中有线程组数量:0 +A处线程:main 所属的线程组名为:main 中有线程组数量:1 +第一个线程组名称为:新的组 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_getGroupParent.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_getGroupParent.java new file mode 100644 index 0000000..8fb4b5a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_getGroupParent.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * p288 + * 获取根线程组 + * JVM根线程组就是system + */ +public class Run2_getGroupParent { + public static void main(String[] args) { + System.out.println("线程:" + Thread.currentThread().getName() + + " 所在的线程组名为:" + Thread.currentThread().getThreadGroup().getName()); + + System.out.println("main线程所在的线程组的父线程组名为:" + + Thread.currentThread().getThreadGroup().getParent().getName()); + + System.out.println("main线程所在的线程组的父线程组的父线程组名为:" + + Thread.currentThread().getThreadGroup().getParent().getParent().getName()); + + } +} + +/* +输出: +线程:main 所在的线程组名为:main +main线程所在的线程组的父线程组名为:system +Exception in thread "main" java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example2.Run2_getGroupParent.main(Run2_getGroupParent.java:20) + 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:483) + at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThread.java new file mode 100644 index 0000000..45e44bd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThread.java @@ -0,0 +1,35 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P286 + * 线程对象关联线程组,一级关联 + */ +public class Run2_groupAddThread { + public static void main(String[] args) { + ThreadA a = new ThreadA(); + ThreadB b = new ThreadB(); + ThreadGroup group = new ThreadGroup("Brian's group"); + Thread athread = new Thread(group, a); + Thread bthread = new Thread(group, b); + athread.start(); + bthread.start(); + System.out.println("活动的线程数为:" + group.activeCount()); + System.out.println("线程组的名称为:" + group.getName()); + } +} + +/* +输出: +活动的线程数为:2 +ThreadName = Thread-3 +ThreadName = Thread-2 +线程组的名称为:Brian's group +ThreadName = Thread-2 +ThreadName = Thread-3 +ThreadName = Thread-2 +ThreadName = Thread-3 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThreadMoreLevel.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThreadMoreLevel.java new file mode 100644 index 0000000..9e9c9fa --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_groupAddThreadMoreLevel.java @@ -0,0 +1,46 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P287 + * 线程对象关联线程组,多级关联 + */ +public class Run2_groupAddThreadMoreLevel { + public static void main(String[] args) { + ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup group = new ThreadGroup(mainGroup, "A"); + Runnable runnable = new Runnable() { + public void run() { + try { + System.out.println("run!"); + Thread.sleep(10000);//运行状态才可以受组管理 + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + Thread newThread = new Thread(group, runnable); + newThread.setName("z"); + newThread.start();//线程启动然后才归到组A + + ThreadGroup[] listGroup = new ThreadGroup[Thread.currentThread().getThreadGroup().activeGroupCount()]; + Thread.currentThread().getThreadGroup().enumerate(listGroup); + System.out.println("main线程中有多少个子线程组:" + listGroup.length + " 名字为:" + listGroup[0].getName()); + Thread[] listThread = new Thread[listGroup[0].activeCount()]; + listGroup[0].enumerate(listThread); + System.out.println(listThread[0].getName()); + + } +} + + +/* +输出: +main线程中有多少个子线程组:1 名字为:A +run! +z + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_threadRunSyn.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_threadRunSyn.java new file mode 100644 index 0000000..fc0f48e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/Run2_threadRunSyn.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P291 + * 使线程具有有序性 + */ +public class Run2_threadRunSyn { + public static void main(String[] args) { + Object lock = new Object(); + MyThread a = new MyThread(lock, "A", 1); + MyThread b = new MyThread(lock, "B", 2); + MyThread c = new MyThread(lock, "C", 0); + a.start(); + b.start(); + c.start(); + } +} + +/* +输出: +ThreadName=Thread-0 runCount = 1 A +ThreadName=Thread-1 runCount = 2 B +ThreadName=Thread-2 runCount = 3 C +ThreadName=Thread-0 runCount = 4 A +ThreadName=Thread-1 runCount = 5 B +ThreadName=Thread-2 runCount = 6 C +ThreadName=Thread-0 runCount = 7 A +ThreadName=Thread-1 runCount = 8 B +ThreadName=Thread-2 runCount = 9 C + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/ThreadA.java new file mode 100644 index 0000000..522d868 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/ThreadA.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ +public class ThreadA extends Thread { + @Override + public void run() { + try { + while (!Thread.currentThread().isInterrupted()) { + System.out.println("ThreadName = " + Thread.currentThread().getName()); + Thread.sleep(3000); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/ThreadB.java new file mode 100644 index 0000000..9b70370 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example2/ThreadB.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.supplement.example2; + +/** + * Created by Brian on 2016/4/17. + */ +public class ThreadB extends Thread { + @Override + public void run() { + try { + while (!Thread.currentThread().isInterrupted()) { + System.out.println("ThreadName = " + Thread.currentThread().getName()); + Thread.sleep(3000); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/DateTools1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/DateTools1.java new file mode 100644 index 0000000..20b6019 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/DateTools1.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by Brian on 2016/4/17. + */ +public class DateTools1 { + public static Date parse(String formatPattern, String dateString) throws ParseException { + return new SimpleDateFormat(formatPattern).parse(dateString); + } + + public static String format(String formatPattern, Date date) { + return new SimpleDateFormat(formatPattern).format(date).toString(); + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/DateTools2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/DateTools2.java new file mode 100644 index 0000000..bff4b22 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/DateTools2.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +import java.text.SimpleDateFormat; + +/** + * Created by Brian on 2016/4/17. + */ +public class DateTools2 { + private static ThreadLocal tl = new ThreadLocal(); + + public static SimpleDateFormat getSimpleDateFormat(String datePattern) { + SimpleDateFormat sdf = null; + sdf = tl.get(); + if (sdf == null) { + sdf = new SimpleDateFormat(datePattern); + tl.set(sdf); + } + return sdf; + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatError.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatError.java new file mode 100644 index 0000000..d802730 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatError.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +/** + * Created by Brian on 2016/4/17. + */ + +import java.text.SimpleDateFormat; + +/** + * P293 + * SimpleDateFormat类非线程安全 + * 有时正常运行,有时报异常 + */ +public class Run3_formatError { + public static void main(String[] args) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String[] dateStringArray = new String[] { + "2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05", + "2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" + }; + Thread0[] threads = new Thread0[10]; + for (int i = 0; i < 10; i++) { + threads[i] = new Thread0(sdf, dateStringArray[i]); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + } +} + +/* +ThreadName = Thread-6报错了 日期字符串:2000-01-07 转换成的日期为1999-12-02 +ThreadName = Thread-4报错了 日期字符串:2000-01-05 转换成的日期为2000-01-09 +ThreadName = Thread-1报错了 日期字符串:2000-01-02 转换成的日期为1999-12-02 +ThreadName = Thread-0报错了 日期字符串:2000-01-01 转换成的日期为2000-01-05 +ThreadName = Thread-5报错了 日期字符串:2000-01-06 转换成的日期为1999-12-03 +Exception in thread "Thread-3" java.lang.NumberFormatException: For input string: "" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Long.parseLong(Long.java:601) + at java.lang.Long.parseLong(Long.java:631) + at java.text.DigitList.getLong(DigitList.java:195) + at java.text.DecimalFormat.parse(DecimalFormat.java:2051) + at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869) + at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514) + at java.text.DateFormat.parse(DateFormat.java:364) + at com.brianway.learning.java.multithread.supplement.example3.Thread0.run(Thread0.java:22) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK1.java new file mode 100644 index 0000000..543b8b3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK1.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +/** + * Created by Brian on 2016/4/17. + */ + +import java.text.SimpleDateFormat; + +/** + * P295 + * SimpleDateFormat类非线程安全,解决异常方法一 + */ +public class Run3_formatOK1 { + public static void main(String[] args) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String[] dateStringArray = new String[] { + "2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05", + "2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" + }; + Thread1[] threads = new Thread1[10]; + for (int i = 0; i < 10; i++) { + threads[i] = new Thread1(sdf, dateStringArray[i]); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + } +} + +/* + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK2.java new file mode 100644 index 0000000..a082358 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Run3_formatOK2.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +/** + * Created by Brian on 2016/4/17. + */ + +import java.text.SimpleDateFormat; + +/** + * P296 + * SimpleDateFormat类非线程安全,解决异常方法二 + */ +public class Run3_formatOK2 { + public static void main(String[] args) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + String[] dateStringArray = new String[] { + "2000-01-01", "2000-01-02", "2000-01-03", "2000-01-04", "2000-01-05", + "2000-01-06", "2000-01-07", "2000-01-08", "2000-01-09", "2000-01-10" + }; + Thread2[] threads = new Thread2[10]; + for (int i = 0; i < 10; i++) { + threads[i] = new Thread2(sdf, dateStringArray[i]); + } + + for (int i = 0; i < 10; i++) { + threads[i].start(); + } + } +} + +/* + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread0.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread0.java new file mode 100644 index 0000000..0d2e742 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread0.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread0 extends Thread { + private SimpleDateFormat sdf; + private String dateString; + + public Thread0(SimpleDateFormat sdf, String dateString) { + this.sdf = sdf; + this.dateString = dateString; + } + + @Override + public void run() { + try { + Date date = sdf.parse(dateString); + String newDateString = sdf.format(date).toString(); + if (!newDateString.equals(dateString)) { + System.out.println("ThreadName = " + this.getName() + + "报错了 日期字符串:" + dateString + + " 转换成的日期为" + newDateString); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread1.java new file mode 100644 index 0000000..0efb3ec --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread1.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread1 extends Thread { + private SimpleDateFormat sdf; + private String dateString; + + public Thread1(SimpleDateFormat sdf, String dateString) { + this.sdf = sdf; + this.dateString = dateString; + } + + @Override + public void run() { + try { + Date date = DateTools1.parse("yyyy-MM-dd", dateString); + String newDateString = DateTools1.format("yyyy-MM-dd", date).toString(); + if (!newDateString.equals(dateString)) { + System.out.println("ThreadName = " + this.getName() + + "报错了 日期字符串:" + dateString + + " 转换成的日期为" + newDateString); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread2.java new file mode 100644 index 0000000..6848937 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example3/Thread2.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.supplement.example3; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread2 extends Thread { + private SimpleDateFormat sdf; + private String dateString; + + public Thread2(SimpleDateFormat sdf, String dateString) { + this.sdf = sdf; + this.dateString = dateString; + } + + @Override + public void run() { + try { + Date date = DateTools2.getSimpleDateFormat("yyyy-MM-dd").parse(dateString); + String newDateString = DateTools2.getSimpleDateFormat("yyyy-MM-dd").format(date).toString(); + if (!newDateString.equals(dateString)) { + System.out.println("ThreadName = " + this.getName() + + "报错了 日期字符串:" + dateString + + " 转换成的日期为" + newDateString); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException.java new file mode 100644 index 0000000..0729ad2 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.supplement.example4; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P297 + * 线程中出现异常 + */ +public class Run4_threadCreateException { + public static void main(String[] args) { + Thread1 t = new Thread1(); + t.start(); + } +} + +/* +输出: +Exception in thread "Thread-0" java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException2.java new file mode 100644 index 0000000..6dc8ec0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException2.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.multithread.supplement.example4; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P298 + * 线程中出现异常,捕捉 + */ +public class Run4_threadCreateException2 { + public static void main(String[] args) { + Thread1 t1 = new Thread1(); + t1.setName("thread t1"); + t1.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + System.out.println("线程:" + t.getName() + " 出现了异常:"); + e.printStackTrace(); + } + }); + t1.start(); + Thread1 t2 = new Thread1(); + t2.setName("thread t2"); + t2.start(); + + } +} + +/* +输出: +线程:thread t1 出现了异常: +Exception in thread "thread t2" java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) +java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) + +------------------------------ + +Exception in thread "thread t2" 线程:thread t1 出现了异常: +java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) +java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException3.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException3.java new file mode 100644 index 0000000..d66fdb5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Run4_threadCreateException3.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.supplement.example4; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P298 + * 线程中出现异常,捕捉 + */ +public class Run4_threadCreateException3 { + public static void main(String[] args) { + Thread1.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + System.out.println("线程:" + t.getName() + " 出现了异常:"); + e.printStackTrace(); + } + }); + Thread1 t1 = new Thread1(); + t1.setName("thread t1"); + t1.start(); + Thread1 t2 = new Thread1(); + t2.setName("thread t2"); + t2.start(); + + } +} + +/* +输出: +java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) +java.lang.NullPointerException + at com.brianway.learning.java.multithread.supplement.example4.Thread1.run(Thread1.java:10) +线程:thread t1 出现了异常: +线程:thread t2 出现了异常: + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Thread1.java new file mode 100644 index 0000000..540f79b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example4/Thread1.java @@ -0,0 +1,12 @@ +package com.brianway.learning.java.multithread.supplement.example4; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread1 extends Thread { + @Override + public void run() { + String username = null; + System.out.println(username.hashCode()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup1.java new file mode 100644 index 0000000..ba87d67 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup1.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.supplement.example5; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * p299 + * 线程组内处理异常 + */ +public class Run5_threadGroup1 { + public static void main(String[] args) { + ThreadGroup group = new ThreadGroup("Brian's group"); + Thread1[] threads = new Thread1[10]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread1(group, "线程" + (i + 1), "1"); + threads[i].start(); + } + Thread1 newT = new Thread1(group, "线程报错", "a"); + newT.start(); + } +} + +/* +一个线程异常不会停止组内其他线程 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup2.java new file mode 100644 index 0000000..7199326 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Run5_threadGroup2.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.supplement.example5; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * p300 + * 线程组内处理异常 + */ +public class Run5_threadGroup2 { + public static void main(String[] args) { + ThreadGroup2 group = new ThreadGroup2("Brian's group"); + Thread2[] threads = new Thread2[10]; + for (int i = 0; i < threads.length; i++) { + threads[i] = new Thread2(group, "线程" + (i + 1), "1"); + threads[i].start(); + } + Thread2 newT = new Thread2(group, "线程报错", "a"); + newT.start(); + } +} + +/* +输出: +死循环中:线程6 +死循环中:线程7 +死循环中:线程8 +死循环中:线程4 +死循环中:线程1 +死循环中:线程5 +死循环中:线程9 +Exception in thread "线程报错" java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example5.Thread2.run(Thread2.java:16) + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Thread1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Thread1.java new file mode 100644 index 0000000..fbf3956 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Thread1.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.supplement.example5; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread1 extends Thread { + private String num; + + public Thread1(ThreadGroup group, String name, String num) { + super(group, name); + this.num = num; + } + + @Override + public void run() { + int numInt = Integer.parseInt(num); + while (true) { + System.out.println("死循环中:" + Thread.currentThread().getName()); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Thread2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Thread2.java new file mode 100644 index 0000000..ecf9820 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/Thread2.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.supplement.example5; + +/** + * Created by Brian on 2016/4/17. + */ +public class Thread2 extends Thread { + private String num; + + public Thread2(ThreadGroup group, String name, String num) { + super(group, name); + this.num = num; + } + + @Override + public void run() { + int numInt = Integer.parseInt(num); + while (this.isInterrupted() == false) { + System.out.println("死循环中:" + Thread.currentThread().getName()); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/ThreadGroup2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/ThreadGroup2.java new file mode 100644 index 0000000..320c9d6 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example5/ThreadGroup2.java @@ -0,0 +1,17 @@ +package com.brianway.learning.java.multithread.supplement.example5; + +/** + * Created by Brian on 2016/4/17. + */ +public class ThreadGroup2 extends ThreadGroup { + + public ThreadGroup2(String name) { + super(name); + } + + @Override + public void uncaughtException(Thread t, Throwable e) { + super.uncaughtException(t, e); + this.interrupt(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/MyThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/MyThread.java new file mode 100644 index 0000000..25d834e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/MyThread.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.supplement.example6; + +/** + * Created by Brian on 2016/4/17. + */ +public class MyThread extends Thread { + private String num = "a"; + + public MyThread() { + } + + public MyThread(MyThreadGroup group, String name) { + super(group, name); + } + + @Override + public void run() { + int numInt = Integer.parseInt(num); + System.out.println("在线程中打印:" + (numInt + 1)); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/MyThreadGroup.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/MyThreadGroup.java new file mode 100644 index 0000000..1ea0148 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/MyThreadGroup.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.supplement.example6; + +/** + * Created by Brian on 2016/4/17. + */ +public class MyThreadGroup extends java.lang.ThreadGroup { + + public MyThreadGroup(String name) { + super(name); + } + + @Override + public void uncaughtException(Thread t, Throwable e) { + super.uncaughtException(t, e); + System.out.println("线程组的异常处理"); + e.printStackTrace(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/ObjectUncaughtExceptionHandler.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/ObjectUncaughtExceptionHandler.java new file mode 100644 index 0000000..b4857f5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/ObjectUncaughtExceptionHandler.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.supplement.example6; + +/** + * Created by Brian on 2016/4/17. + */ + +import java.lang.Thread.UncaughtExceptionHandler; + +public class ObjectUncaughtExceptionHandler implements UncaughtExceptionHandler { + public void uncaughtException(Thread t, Throwable e) { + System.out.println("对象的异常处理"); + e.printStackTrace(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove1.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove1.java new file mode 100644 index 0000000..e1262c4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove1.java @@ -0,0 +1,50 @@ +package com.brianway.learning.java.multithread.supplement.example6; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P303 + */ +public class Run6_threadExceptionMove1 { + public static void main(String[] args) { + MyThread myThread = new MyThread(); + //对象 + //myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); + //类 + MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); + + myThread.start(); + } + +} + +/* +//对象 +myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); +//类 +MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); +输出: +对象的异常处理 +java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) + + +--------------------------- +//对象 +//myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); +//类 +MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); +输出: +静态的异常处理 +java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove2.java new file mode 100644 index 0000000..307d335 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/Run6_threadExceptionMove2.java @@ -0,0 +1,76 @@ +package com.brianway.learning.java.multithread.supplement.example6; + +/** + * Created by Brian on 2016/4/17. + */ + +/** + * P304 + */ +public class Run6_threadExceptionMove2 { + public static void main(String[] args) { + MyThreadGroup group = new MyThreadGroup("我的线程组"); + + MyThread myThread = new MyThread(group, "我的线程"); + //对象 + //myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); + //类 + //MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); + + myThread.start(); + } + +} + +/* +//对象 +myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); +//类 +MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); +输出: +对象的异常处理 +java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) + + +--------------------------- +//对象 +//myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); +//类 +MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); +输出: +java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) +java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) +静态的异常处理 +线程组的异常处理 + + +-------------------------------- +//对象 +//myThread.setUncaughtExceptionHandler(new ObjectUncaughtExceptionHandler()); +//类 +//MyThread.setDefaultUncaughtExceptionHandler(new StateUncaughtExceptionHandler()); +输出: +Exception in thread "我的线程" java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) +java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.supplement.example6.MyThread.run(MyThread.java:18) +线程组的异常处理 + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/StateUncaughtExceptionHandler.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/StateUncaughtExceptionHandler.java new file mode 100644 index 0000000..5f4bc66 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/supplement/example6/StateUncaughtExceptionHandler.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.supplement.example6; + +/** + * Created by Brian on 2016/4/17. + */ + +import java.lang.Thread.UncaughtExceptionHandler; + +public class StateUncaughtExceptionHandler implements UncaughtExceptionHandler { + public void uncaughtException(Thread t, Throwable e) { + System.out.println("静态的异常处理"); + e.printStackTrace(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/HasLocalNum.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/HasLocalNum.java new file mode 100644 index 0000000..ca78e1d --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/HasLocalNum.java @@ -0,0 +1,25 @@ +package com.brianway.learning.java.multithread.synchronize.example1; + +/** + * Created by Brian on 2016/4/11. + */ + +public class HasLocalNum { + public void addI(String username) { + try { + int num = 0; + if (username.equals("a")) { + num = 100; + System.out.println("a set over"); + Thread.sleep(1000); + + } else { + num = 200; + System.out.println("b set over"); + } + 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/example1/Run1_local.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/Run1_local.java new file mode 100644 index 0000000..765e427 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/Run1_local.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.synchronize.example1; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P53例子 + * 方法内局部变量则不存在“非线程安全”问题 + */ + +public class Run1_local { + public static void main(String[] args) { + HasLocalNum numRef = new HasLocalNum(); + ThreadA threadA = new ThreadA(numRef); + threadA.start(); + ThreadB threadB = new ThreadB(numRef); + threadB.start(); + } +} + + +/* +输出: +a set over +b set over +b num= 200 +a num= 100 + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/ThreadA.java new file mode 100644 index 0000000..9e0d150 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/ThreadA.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example1; + +/** + * Created by Brian on 2016/4/11. + */ +public class ThreadA extends Thread { + private HasLocalNum numRef; + + public ThreadA(HasLocalNum numRef) { + super(); + this.numRef = numRef; + } + + @Override + public void run() { + super.run(); + numRef.addI("a"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/ThreadB.java new file mode 100644 index 0000000..c373dff --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example1/ThreadB.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example1; + +/** + * Created by Brian on 2016/4/11. + */ +public class ThreadB extends Thread { + private HasLocalNum numRef; + + public ThreadB(HasLocalNum numRef) { + super(); + this.numRef = numRef; + } + + @Override + public void run() { + super.run(); + numRef.addI("b"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synBlockMoreObjectOneLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synBlockMoreObjectOneLock.java new file mode 100644 index 0000000..0744b89 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synBlockMoreObjectOneLock.java @@ -0,0 +1,95 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ + +/** + * P101 + * 验证同步synchronized(class)代码块的作用 + * 顺便验证了下static方法是不能复写的 + * + * @see ServiceSub,ServiceSub2 + */ +public class Run10_synBlockMoreObjectOneLock { + public static void main(String[] args) { + //testSub(); + //testSub2(); + testBlock(); + } + + /** + * 验证同步sychronized(class)代码块的作用 + */ + public static void testBlock() { + final ServiceSub service1 = new ServiceSub(); + final ServiceSub service2 = new ServiceSub(); + + Thread a = new Thread() { + @Override + public void run() { + service1.printA(); + } + }; + a.setName("A"); + a.start(); + Thread b = new Thread() { + @Override + public void run() { + service2.printB(); + } + }; + b.setName("B"); + b.start(); + } + + /** + * testSub断点调试结果是运行的Service类的printA方法 + */ + public static void testSub() { + ServiceSub service1 = new ServiceSub(); + ServiceSub service2 = new ServiceSub(); + + ThreadA a = new ThreadA(service1); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(service2); + b.setName("B"); + b.start(); + } + + /** + * testSub2断点调试结果是运行的Service类的printA方法 + */ + public static void testSub2() { + ServiceSub2 service1 = new ServiceSub2(); + ServiceSub2 service2 = new ServiceSub2(); + + ThreadA a = new ThreadA(service1); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(service2); + b.setName("B"); + b.start(); + } + +} + + +/* +输出: +In ServiceSub +线程名:A 在 1460480421944进入printA +线程名:A 在 1460480423944离开printA +线程名:B 在 1460480423944进入printB +线程名:B 在 1460480423944离开printB + +--------- +也可能: +线程名:B 在 1460480476089进入printB +线程名:B 在 1460480476089离开printB +In ServiceSub +线程名:A 在 1460480476089进入printA +线程名:A 在 1460480478089离开printA + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synMoreObjectStaticOneLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synMoreObjectStaticOneLock.java new file mode 100644 index 0000000..12176a4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synMoreObjectStaticOneLock.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ + +/** + * P100 + * Class锁可以对类的所有对象实例起作用 + */ +public class Run10_synMoreObjectStaticOneLock { + public static void main(String[] args) { + Service service1 = new Service(); + Service service2 = new Service(); + + ThreadA a = new ThreadA(service1); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(service2); + b.setName("B"); + b.start(); + + } +} + +/* +输出: +线程名:A 在 1460479094611进入printA +线程名:A 在 1460479097611离开printA +线程名:B 在 1460479097611进入printB +线程名:B 在 1460479097611离开printB + */ diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synTwoLock.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synTwoLock.java new file mode 100644 index 0000000..21e7b0f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Run10_synTwoLock.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ + +/** + * P97 + * 验证synchronized关键字加载static静态方法和加到非静态方法不是同一个锁 + * 一个是Class类上锁,一个是对象上锁 + */ +public class Run10_synTwoLock { + public static void main(String[] args) { + Service service = new Service(); + + ThreadA a = new ThreadA(service); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(service); + b.setName("B"); + b.start(); + ThreadC c = new ThreadC(service); + c.setName("C"); + c.start(); + } +} + +/* +输出: +线程名:A 在 1460478479803进入printA +线程名:C 在 1460478479808进入printC +线程名:C 在 1460478479808离开printC +线程名:A 在 1460478482804离开printA +线程名:B 在 1460478482804进入printB +线程名:B 在 1460478482804离开printB + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Service.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Service.java new file mode 100644 index 0000000..c70d6ee --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/Service.java @@ -0,0 +1,27 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ + +public class Service { + synchronized public static void printA() { + try { + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printA"); + Thread.sleep(3000); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printA"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public static void printB() { + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printB"); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printB"); + } + + synchronized public void printC() { + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printC"); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printC"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ServiceSub.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ServiceSub.java new file mode 100644 index 0000000..74cb4d4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ServiceSub.java @@ -0,0 +1,29 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ +public class ServiceSub extends Service { + + public static void printA() { + synchronized (ServiceSub.class) { + try { + System.out.println("In ServiceSub"); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printA"); + Thread.sleep(2000); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printA"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void printB() { + synchronized (ServiceSub.class) { + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printB"); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printB"); + } + + } + +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ServiceSub2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ServiceSub2.java new file mode 100644 index 0000000..762f272 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ServiceSub2.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ +public class ServiceSub2 extends Service { + synchronized public static void printA() { + try { + System.out.println("ServiceSub2"); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printA"); + Thread.sleep(1000); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printA"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized public static void printB() { + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "进入printB"); + System.out.println("线程名:" + Thread.currentThread().getName() + " 在 " + System.currentTimeMillis() + "离开printB"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadA.java new file mode 100644 index 0000000..7a229b1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadA.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ +public class ThreadA extends Thread { + private Service service; + + public ThreadA(Service service) { + super(); + this.service = service; + } + + @Override + public void run() { + service.printA(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadB.java new file mode 100644 index 0000000..a07d541 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadB.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ +public class ThreadB extends Thread { + private Service service; + + public ThreadB(Service service) { + super(); + this.service = service; + } + + @Override + public void run() { + service.printB(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadC.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadC.java new file mode 100644 index 0000000..37c44f9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example10/ThreadC.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example10; + +/** + * Created by brian on 2016/4/13. + */ +public class ThreadC extends Thread { + private Service service; + + public ThreadC(Service service) { + super(); + this.service = service; + } + + @Override + public void run() { + service.printC(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn.java new file mode 100644 index 0000000..fb61589 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.multithread.synchronize.example11; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P102 + * String作为锁对象 + * 常量池->同一锁 + */ +public class Run11_StringAndSyn { + public static void main(String[] args) { + ServiceA serviceA = new ServiceA(); + ThreadA a = new ThreadA(serviceA); + a.setName("A"); + a.start(); + ThreadA b = new ThreadA(serviceA); + b.setName("B"); + b.start(); + } +} + + +/* +输出: +A +A +A +A +A +A +A +A + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn2.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn2.java new file mode 100644 index 0000000..9bb7710 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/Run11_StringAndSyn2.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.synchronize.example11; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P104 + * 不使用String作为锁对象 + */ +public class Run11_StringAndSyn2 { + public static void main(String[] args) { + ServiceB serviceB = new ServiceB(); + ThreadB a = new ThreadB(serviceB); + a.setName("A"); + a.start(); + ThreadB b = new ThreadB(serviceB); + b.setName("B"); + b.start(); + } +} + + +/* +输出: +A +B +B +A +A +B +A +B +A +B +B +A +A +B + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ServiceA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ServiceA.java new file mode 100644 index 0000000..c53cb19 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ServiceA.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.synchronize.example11; + +/** + * Created by Brian on 2016/4/13. + */ +public class ServiceA { + public static void print(String stringParam) { + try { + synchronized (stringParam) { + while (true) { + System.out.println(Thread.currentThread().getName()); + Thread.sleep(1000); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ServiceB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ServiceB.java new file mode 100644 index 0000000..4bf2aac --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ServiceB.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.synchronize.example11; + +/** + * Created by Brian on 2016/4/13. + */ +public class ServiceB { + public static void print(Object object) { + try { + synchronized (object) { + while (true) { + System.out.println(Thread.currentThread().getName()); + Thread.sleep(500); + } + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ThreadA.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ThreadA.java new file mode 100644 index 0000000..bb150b8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ThreadA.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example11; + +/** + * Created by Brian on 2016/4/13. + */ +public class ThreadA extends Thread { + ServiceA serviceA; + + public ThreadA(ServiceA serviceA) { + super(); + this.serviceA = serviceA; + } + + @Override + public void run() { + serviceA.print("123"); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ThreadB.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ThreadB.java new file mode 100644 index 0000000..375d02f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example11/ThreadB.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example11; + +/** + * Created by Brian on 2016/4/13. + */ +public class ThreadB extends Thread { + ServiceB serviceB; + + public ThreadB(ServiceB serviceB) { + super(); + this.serviceB = serviceB; + } + + @Override + public void run() { + serviceB.print(new Object()); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/DealThread.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/DealThread.java new file mode 100644 index 0000000..00547dc --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/DealThread.java @@ -0,0 +1,46 @@ +package com.brianway.learning.java.multithread.synchronize.example12; + +/** + * Created by Brian on 2016/4/13. + */ +public class DealThread implements Runnable { + public String username; + + public Object lock1 = new Object(); + public Object lock2 = new Object(); + + public void setFlag(String username) { + this.username = username; + } + + public void run() { + if (username.equals("a")) { + synchronized (lock1) { + try { + System.out.println("username = " + username); + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + synchronized (lock2) { + System.out.println("按lock1->lock2代码顺序执行"); + } + } + } + if (username.equals("b")) { + synchronized (lock2) { + try { + System.out.println("username = " + username); + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + 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 new file mode 100644 index 0000000..7b982cd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example12/Run12_deadLock.java @@ -0,0 +1,198 @@ +package com.brianway.learning.java.multithread.synchronize.example12; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P107 + * 死锁测试 + * jstack命令 + */ +public class Run12_deadLock { + public static void main(String[] args) { + try { + DealThread t1 = new DealThread(); + t1.setFlag("a"); + Thread thread1 = new Thread(t1); + thread1.start(); + Thread.sleep(100); + t1.setFlag("b"); + Thread thread2 = new Thread(t1); + thread2.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} + + +/* +输出: +username = a +username = b + +--------------------------- + + +G:\mygit\java-learning>jps +4752 +7524 Jps +8936 Launcher + +(启动Run12_deadLock的main方法) + +G:\mygit\java-learning> +G:\mygit\java-learning>jps +4752 +8948 AppMain +6344 Jps +8732 Launcher + +G:\mygit\java-learning>jstack -l 8948 +2016-04-13 15:04:01 +Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode): + +"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x00000000022df000 nid=0x18dc waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"Thread-1" #12 prio=5 os_prio=0 tid=0x0000000058773800 nid=0x20f0 waiting for monitor entry [0x0000000059c1f000] + java.lang.Thread.State: BLOCKED (on object monitor) + at com.brianway.learning.java.multithread.synchronize.example12.DealThread.run(DealThread.java:41) + - waiting to lock <0x00000000d61411d0> (a java.lang.Object) + - locked <0x00000000d61411e0> (a java.lang.Object) + at java.lang.Thread.run(Thread.java:745) + + Locked ownable synchronizers: + - None + +"Thread-0" #11 prio=5 os_prio=0 tid=0x000000005875a000 nid=0x1de8 waiting for monitor entry [0x00000000599bf000] + java.lang.Thread.State: BLOCKED (on object monitor) + at com.brianway.learning.java.multithread.synchronize.example12.DealThread.run(DealThread.java:27) + - waiting to lock <0x00000000d61411e0> (a java.lang.Object) + - locked <0x00000000d61411d0> (a java.lang.Object) + at java.lang.Thread.run(Thread.java:745) + + Locked ownable synchronizers: + - None + +"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=0 tid=0x000000005876e800 nid=0x1f50 runnable [0x000000005969f000] + java.lang.Thread.State: RUNNABLE + at java.net.DualStackPlainSocketImpl.accept0(Native Method) + at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131) + at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404) + at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199) + - locked <0x00000000d621bce8> (a java.net.SocksSocketImpl) + at java.net.ServerSocket.implAccept(ServerSocket.java:545) + at java.net.ServerSocket.accept(ServerSocket.java:513) + at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:90) + at java.lang.Thread.run(Thread.java:745) + + Locked ownable synchronizers: + - None + +"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000005736f800 nid=0x2194 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x0000000058698800 nid=0x2330 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x0000000058697800 nid=0x96c waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x0000000058646800 nid=0x1fac waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x000000005863a800 nid=0x2268 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000005735d000 nid=0x1e2c runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000057306800 nid=0x62c in Object.wait() [0x000000005836f000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait(Native Method) + - waiting on <0x00000000d5f86280> (a java.lang.ref.ReferenceQueue$Lock) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:142) + - locked <0x00000000d5f86280> (a java.lang.ref.ReferenceQueue$Lock) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:158) + at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) + + Locked ownable synchronizers: + - None + +"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000572fd800 nid=0x2254 in Object.wait() [0x000000005862f000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait(Native Method) + - waiting on <0x00000000d5f85cf0> (a java.lang.ref.Reference$Lock) + at java.lang.Object.wait(Object.java:502) + at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157) + - locked <0x00000000d5f85cf0> (a java.lang.ref.Reference$Lock) + + Locked ownable synchronizers: + - None + +"VM Thread" os_prio=2 tid=0x00000000572f7000 nid=0x1ba8 runnable + +"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x000000000214d000 nid=0x2274 runnable + +"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x000000000214e800 nid=0x1a74 runnable + +"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002150000 nid=0xad8 runnable + +"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002151800 nid=0x668 runnable + +"VM Periodic Task Thread" os_prio=2 tid=0x00000000586b0800 nid=0x2150 waiting on condition + +JNI global references: 20 + + +Found one Java-level deadlock: +============================= +"Thread-1": + waiting to lock monitor 0x0000000057304218 (object 0x00000000d61411d0, a java.lang.Object), + which is held by "Thread-0" +"Thread-0": + waiting to lock monitor 0x0000000057300228 (object 0x00000000d61411e0, a java.lang.Object), + which is held by "Thread-1" + +Java stack information for the threads listed above: +=================================================== +"Thread-1": + at com.brianway.learning.java.multithread.synchronize.example12.DealThread.run(DealThread.java:41) + - waiting to lock <0x00000000d61411d0> (a java.lang.Object) + - locked <0x00000000d61411e0> (a java.lang.Object) + at java.lang.Thread.run(Thread.java:745) +"Thread-0": + at com.brianway.learning.java.multithread.synchronize.example12.DealThread.run(DealThread.java:27) + - waiting to lock <0x00000000d61411e0> (a java.lang.Object) + - locked <0x00000000d61411d0> (a java.lang.Object) + at java.lang.Thread.run(Thread.java:745) + +Found 1 deadlock. + + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..bfa8da8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.multithread.synchronize.example13; + +/** + * Created by Brian on 2016/4/13. + */ +public class OutClass { + static class Inner { + public void method1() { + synchronized ("其他的锁") { + for (int i = 1; i <= 10; i++) { + System.out.println(Thread.currentThread().getName() + " i=" + i); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + 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) { + e.printStackTrace(); + } + } + } + } +} 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 new file mode 100644 index 0000000..27bb7da --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/OutClass2.java @@ -0,0 +1,59 @@ +package com.brianway.learning.java.multithread.synchronize.example13; + +/** + * Created by Brian on 2016/4/13. + */ +public class OutClass2 { + static class InnerClass1 { + public void method1(InnerClass2 class2) { + String threadName = Thread.currentThread().getName(); + synchronized (class2) { + System.out.println(threadName + " 进入InnerClass1类中的method1方法"); + for (int i = 1; i <= 10; i++) { + System.out.println("i=" + i); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println(threadName + " 离开InnerClass1类中的method1方法"); + } + } + + public synchronized void method2() { + String threadName = Thread.currentThread().getName(); + + System.out.println(threadName + " 进入InnerClass1类中的method2方法"); + for (int j = 1; j <= 10; j++) { + System.out.println("j=" + j); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println(threadName + " 离开InnerClass1类中的method2方法"); + + } + + } + + static class InnerClass2 { + public synchronized void method1() { + String threadName = Thread.currentThread().getName(); + + System.out.println(threadName + " 进入InnerClass2类中的method2方法"); + for (int k = 1; k <= 10; k++) { + System.out.println("k=" + k); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + 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 new file mode 100644 index 0000000..21bbe0c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner01.java @@ -0,0 +1,53 @@ +package com.brianway.learning.java.multithread.synchronize.example13; + +/** + * 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"); + Thread t2 = new Thread(new Runnable() { + public void run() { + inner.method2(); + } + }, "B"); + t1.start(); + t2.start(); + } +} + +/* +输出: +A i=1 +B i=11 +B i=12 +A i=2 +A i=3 +B i=13 +B i=14 +A i=4 +A i=5 +B i=15 +B i=16 +A i=6 +B i=17 +A i=7 +A i=8 +B i=18 +B i=19 +A i=9 +A i=10 +B i=20 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..b93a5b7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example13/Run13_inner02.java @@ -0,0 +1,177 @@ +package com.brianway.learning.java.multithread.synchronize.example13; + +/** + * 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 + */ + +/** + * P112 + * 内置类与同步测试2 + * + * T1和T3竞争in2的锁。只有T1结束,T3才能开始;或者T3结束,T1才能开始 + * T2与另外两个没关系,因为其锁对象是in2 + */ + +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(); + final InnerClass2 in2 = new InnerClass2(); + Thread t1 = new Thread(new Runnable() { + public void run() { + in1.method1(in2); + } + }, "T1"); + + Thread t2 = new Thread(new Runnable() { + public void run() { + in1.method2(); + } + }, "T2"); + + Thread t3 = new Thread(new Runnable() { + public void run() { + in2.method1(); + } + }, "T3"); + + t1.start(); + t2.start(); + t3.start(); + + } +} + + +/* +输出: +T1 进入InnerClass1类中的method1方法 +i=1 +T2 进入InnerClass1类中的method2方法 +j=1 +j=2 +i=2 +j=3 +i=3 +j=4 +i=4 +j=5 +i=5 +j=6 +i=6 +j=7 +i=7 +i=8 +j=8 +i=9 +j=9 +j=10 +i=10 +T2 离开InnerClass1类中的method2方法 +T1 离开InnerClass1类中的method1方法 +T3 进入InnerClass2类中的method2方法 +k=1 +k=2 +k=3 +k=4 +k=5 +k=6 +k=7 +k=8 +k=9 +k=10 +T3 离开InnerClass2类中的method2方法 + + +-------------------------- + +T1 进入InnerClass1类中的method1方法 +i=1 +T2 进入InnerClass1类中的method2方法 +j=1 +j=2 +i=2 +i=3 +j=3 +j=4 +i=4 +i=5 +j=5 +j=6 +i=6 +j=7 +i=7 +i=8 +j=8 +i=9 +j=9 +j=10 +i=10 +T1 离开InnerClass1类中的method1方法 +T3 进入InnerClass2类中的method2方法 +k=1 +T2 离开InnerClass1类中的method2方法 +k=2 +k=3 +k=4 +k=5 +k=6 +k=7 +k=8 +k=9 +k=10 +T3 离开InnerClass2类中的method2方法 + +------------------------------- +T3 进入InnerClass2类中的method2方法 +k=1 +T2 进入InnerClass1类中的method2方法 +j=1 +k=2 +j=2 +k=3 +j=3 +j=4 +k=4 +j=5 +k=5 +k=6 +j=6 +k=7 +j=7 +k=8 +j=8 +k=9 +j=9 +k=10 +j=10 +T3 离开InnerClass2类中的method2方法 +T1 进入InnerClass1类中的method1方法 +i=1 +T2 离开InnerClass1类中的method2方法 +i=2 +i=3 +i=4 +i=5 +i=6 +i=7 +i=8 +i=9 +i=10 +T1 离开InnerClass1类中的method1方法 + + */ 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 new file mode 100644 index 0000000..83cd9a7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Run14_setNewStringTwoLock.java @@ -0,0 +1,53 @@ +package com.brianway.learning.java.multithread.synchronize.example14; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P114 + * 锁对象改变 + */ +public class Run14_setNewStringTwoLock { + public static void main(String[] args) throws InterruptedException { + final Service service = new Service(); + Thread a = new Thread() { + @Override + public void run() { + service.testMethod(); + } + }; + a.setName("A"); + Thread b = new Thread() { + @Override + public void run() { + service.testMethod(); + } + }; + b.setName("B"); + + a.start(); + Thread.sleep(50); + b.start(); + + } +} + + +/* +输出: +A begin 1460536381652 +B begin 1460536381702 +A end 1460536383652 +B end 1460536383702 + + +-------------- + +//Thread.sleep(50); +输出: +A begin 1460536503287 +A end 1460536505287 +B begin 1460536505287 +B end 1460536507287 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..bfeda5f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example14/Service.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.synchronize.example14; + +/** + * Created by Brian on 2016/4/13. + */ +public class Service { + private String lock = "123"; + + public void testMethod() { + try { + 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()); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} 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 new file mode 100644 index 0000000..c9ccc3c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_synchronized.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.synchronize.example15; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P130 + * synchronized代码块有volatile同步的功能 + */ +public class Run15_synchronized { + public static void main(String[] args) { + try { + RunThread2 t = new RunThread2(); + t.start(); + Thread.sleep(1000); + t.setRunning(false); + System.out.println("已经赋值为false"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + + +/* +输出: +进入run了 +线程被停止了 +已经赋值为false + +----------------- +注释掉RunThread2类中的synchronized ("any thing"){} +输出: +进入run了 +已经赋值为false + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_volatile.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_volatile.java new file mode 100644 index 0000000..10b4c9b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/Run15_volatile.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.synchronize.example15; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P121 + * 不使用volatile关键字 + * JVM配置 -server(IDEA15.02,jdk1.8,WIN7,64bit不加效果也是的) + */ +public class Run15_volatile { + public static void main(String[] args) { + try { + RunThread t = new RunThread(); + t.start(); + Thread.sleep(1000); + t.setRunning(false); + System.out.println("已经赋值为false"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} + + +/* +输出: +进入run了 +已经赋值为false + +-------------- +加上volatile关键字后 +输出: +进入run了 +已经赋值为false +线程被停止了 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..48df5b5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.synchronize.example15; + +/** + * Created by Brian on 2016/4/13. + */ +public class RunThread extends Thread { + private boolean isRunning = true; + //volatile private boolean isRunning = true; + + public boolean isRunning() { + return isRunning; + } + + public void setRunning(boolean running) { + isRunning = running; + } + + @Override + public void run() { + System.out.println("进入run了"); + 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 new file mode 100644 index 0000000..ccf5b68 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example15/RunThread2.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.synchronize.example15; + +/** + * Created by Brian on 2016/4/13. + */ +public class RunThread2 extends Thread { + private boolean isRunning = true; + + public boolean isRunning() { + return isRunning; + } + + public void setRunning(boolean running) { + isRunning = running; + } + + @Override + public void run() { + System.out.println("进入run了"); + 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 new file mode 100644 index 0000000..4adef41 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/MyThread.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.synchronize.example16; + +/** + * Created by Brian on 2016/4/13. + */ +public class MyThread extends Thread { + volatile public static int count; + + //synchronized + private static void addCount() { + for (int i = 0; i < 100; i++) { + count++; + } + System.out.println("count=" + count); + } + + @Override + public void run() { + addCount(); + } +} 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 new file mode 100644 index 0000000..055d320 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example16/Run16_volatile.java @@ -0,0 +1,232 @@ +package com.brianway.learning.java.multithread.synchronize.example16; + +/** + * Created by Brian on 2016/4/13. + */ + +/** + * P124 + * volatile非原子的特性 + */ +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].start(); + } + + } +} + +/* +addCount不加synchronized +输出: +count=200 +count=200 +count=300 +count=400 +count=500 +count=600 +count=700 +count=800 +count=900 +count=1000 +count=1100 +count=1200 +count=1300 +count=1400 +count=1500 +count=1600 +count=1700 +count=1800 +count=1900 +count=2000 +count=2100 +count=2200 +count=2300 +count=2400 +count=2500 +count=2600 +count=2700 +count=2800 +count=2900 +count=3000 +count=3100 +count=3200 +count=3300 +count=3400 +count=3500 +count=3600 +count=3700 +count=3800 +count=3900 +count=4000 +count=4100 +count=4200 +count=4300 +count=4400 +count=4500 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9456 +count=9556 +count=9456 +count=9656 +count=9756 +count=9756 +count=9756 +count=9856 +count=9456 +count=9456 +count=9456 +count=9456 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9756 +count=9756 +count=9656 +count=9556 +count=9556 +count=9956 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 +count=9856 + + +----------------------------- +addCount()加synchronized +输出: +count=100 +count=200 +count=300 +count=400 +count=500 +count=600 +count=700 +count=800 +count=900 +count=1000 +count=1100 +count=1200 +count=1300 +count=1400 +count=1500 +count=1600 +count=1700 +count=1800 +count=1900 +count=2000 +count=2100 +count=2200 +count=2300 +count=2400 +count=2500 +count=2600 +count=2700 +count=2800 +count=2900 +count=3000 +count=3100 +count=3200 +count=3300 +count=3400 +count=3500 +count=3600 +count=3700 +count=3800 +count=3900 +count=4000 +count=4100 +count=4200 +count=4300 +count=4400 +count=4500 +count=4600 +count=4700 +count=4800 +count=4900 +count=5000 +count=5100 +count=5200 +count=5300 +count=5400 +count=5500 +count=5600 +count=5700 +count=5800 +count=5900 +count=6000 +count=6100 +count=6200 +count=6300 +count=6400 +count=6500 +count=6600 +count=6700 +count=6800 +count=6900 +count=7000 +count=7100 +count=7200 +count=7300 +count=7400 +count=7500 +count=7600 +count=7700 +count=7800 +count=7900 +count=8000 +count=8100 +count=8200 +count=8300 +count=8400 +count=8500 +count=8600 +count=8700 +count=8800 +count=8900 +count=9000 +count=9100 +count=9200 +count=9300 +count=9400 +count=9500 +count=9600 +count=9700 +count=9800 +count=9900 +count=10000 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..c50898a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/HasSelfPrivateNum.java @@ -0,0 +1,26 @@ +package com.brianway.learning.java.multithread.synchronize.example2; + +/** + * Created by Brian on 2016/4/11. + */ +public class HasSelfPrivateNum { + private int num = 0; + + synchronized + public void addI(String username) { + try { + if (username.equals("a")) { + num = 100; + System.out.println("a set over"); + Thread.sleep(2000); + + } else { + num = 200; + System.out.println("b set over"); + } + 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 new file mode 100644 index 0000000..4b56d00 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_private01.java @@ -0,0 +1,39 @@ +package com.brianway.learning.java.multithread.synchronize.example2; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P55 + * 实例变量非线程安全 + */ +public class Run2_private01 { + public static void main(String[] args) { + HasSelfPrivateNum numRef = new HasSelfPrivateNum(); + ThreadA threadA = new ThreadA(numRef); + threadA.start(); + ThreadB threadB = new ThreadB(numRef); + threadB.start(); + } +} + +/* +//synchronized + public void addI(String username) +输出: +a set over +b set over +b num= 200 +a num= 200 + +--------------- +HasSelfPrivateNum中addI加synchronized +输出:(注意顺序) +a set over +a num= 100 +b set over +b num= 200 + + + */ \ No newline at end of file diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_twoObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_twoObject.java new file mode 100644 index 0000000..cac55a5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/Run2_twoObject.java @@ -0,0 +1,32 @@ +package com.brianway.learning.java.multithread.synchronize.example2; + +/** + * Created by Brian on 2016/4/11. + */ + +/** + * P58 + * 多个对象多个锁 + * 关键字synchronized取得的都是对象锁 + * 由于两个对象,所以是两个锁,没有同步问题。运行结果异步 + */ +public class Run2_twoObject { + public static void main(String[] args) { + HasSelfPrivateNum numRef1 = new HasSelfPrivateNum(); + HasSelfPrivateNum numRef2 = new HasSelfPrivateNum(); + ThreadA threadA = new ThreadA(numRef1); + threadA.start(); + ThreadB threadB = new ThreadB(numRef2); + threadB.start(); + } +} + + +/* +synchronized public void addI +输出:(注意顺序,由于两个对象,所以是两个锁,没有同步问题。运行结果异步) +a set over +b set over +b num= 200 +a num= 100 +*/ \ No newline at end of file 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 new file mode 100644 index 0000000..d10c147 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadA.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example2; + +/** + * Created by Brian on 2016/4/11. + */ +public class ThreadA extends Thread { + private HasSelfPrivateNum numRef; + + public ThreadA(HasSelfPrivateNum numRef) { + super(); + this.numRef = numRef; + } + + @Override + public void run() { + super.run(); + numRef.addI("a"); + } +} 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 new file mode 100644 index 0000000..95d69a5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example2/ThreadB.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example2; + +/** + * Created by Brian on 2016/4/11. + */ +public class ThreadB extends Thread { + private HasSelfPrivateNum numRef; + + public ThreadB(HasSelfPrivateNum numRef) { + super(); + this.numRef = numRef; + } + + @Override + public void run() { + super.run(); + numRef.addI("b"); + } +} 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 new file mode 100644 index 0000000..3a9275e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/MyObject.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example3; + +/** + * Created by Brian on 2016/4/12. + */ + +public class MyObject { + synchronized + public void methodA() { + try { + System.out.println("begin methodA threadName=" + Thread.currentThread().getName()); + Thread.sleep(5000); + 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 new file mode 100644 index 0000000..3ec5fbd --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/Run3_synchronized01.java @@ -0,0 +1,40 @@ +package com.brianway.learning.java.multithread.synchronize.example3; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P60 + * synchronized方法与锁对象 + */ +public class Run3_synchronized01 { + public static void main(String[] args) { + MyObject object = new MyObject(); + ThreadA a = new ThreadA(object); + a.setName("A "); + ThreadB b = new ThreadB(object); + b.setName("B "); + a.start(); + b.start(); + } +} + +/* +public void methodA()没加synchronized +输出: +begin methodA threadName=B +begin methodA threadName=A +A end +B end + +------------------- + +public void methodA()加synchronized +输出: +begin methodA threadName=A +A end +begin methodA threadName=B +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 new file mode 100644 index 0000000..0cb786e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadA.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example3; + +/** + * Created by Brian on 2016/4/12. + */ +public class ThreadA extends Thread { + private MyObject object; + + public ThreadA(MyObject object) { + super(); + this.object = object; + } + + @Override + public void run() { + super.run(); + object.methodA(); + } +} 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 new file mode 100644 index 0000000..bd32dda --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example3/ThreadB.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example3; + +/** + * Created by Brian on 2016/4/12. + */ +public class ThreadB extends Thread { + private MyObject object; + + public ThreadB(MyObject object) { + super(); + this.object = object; + } + + @Override + public void run() { + super.run(); + object.methodA(); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..09aa105 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/MyObject.java @@ -0,0 +1,28 @@ +package com.brianway.learning.java.multithread.synchronize.example4; + +/** + * Created by Brian on 2016/4/12. + */ + +public class MyObject { + synchronized public void methodA() { + try { + System.out.println("begin methodA threadName=" + Thread.currentThread().getName()); + Thread.sleep(5000); + System.out.println(Thread.currentThread().getName() + " endTime:" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + synchronized + public void methodB() { + try { + System.out.println("begin methodB threadName=" + Thread.currentThread().getName()); + Thread.sleep(5000); + 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/Run4_synchronized01.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/Run4_synchronized01.java new file mode 100644 index 0000000..6310135 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/Run4_synchronized01.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.synchronize.example4; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P63 + * 两个线程访问同一个对象的不同方法 + * 1.一个方法有synchronized,一个没有。线程B可异步调用非synchronized类型方法 + * 2.两个都有synchronized。线程B需等待 + */ +public class Run4_synchronized01 { + public static void main(String[] args) { + MyObject object = new MyObject(); + ThreadA a = new ThreadA(object); + a.setName("A"); + ThreadB b = new ThreadB(object); + b.setName("B"); + a.start(); + b.start(); + } +} + +/* +public void methodB()没加synchronized +输出: +begin methodA threadName=A +begin methodB threadName=B +A endTime:1460449260181 +B endTime:1460449260181 + +------------------- + +public void methodB()加synchronized +输出: +begin methodA threadName=A +A endTime:1460449301441 +begin methodB threadName=B +B endTime:1460449306441 + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..85c1995 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadA.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example4; + +/** + * Created by Brian on 2016/4/12. + */ +public class ThreadA extends Thread { + private MyObject object; + + public ThreadA(MyObject object) { + super(); + this.object = object; + } + + @Override + public void run() { + super.run(); + object.methodA(); + } +} 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 new file mode 100644 index 0000000..0e4b447 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example4/ThreadB.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example4; + +/** + * Created by Brian on 2016/4/12. + */ +public class ThreadB extends Thread { + private MyObject object; + + public ThreadB(MyObject object) { + super(); + this.object = object; + } + + @Override + public void run() { + super.run(); + object.methodB(); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..48bf667 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Main.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example5; + +/** + * Created by Brian on 2016/4/12. + */ +public class Main { + protected int i = 10; + + synchronized public void operateIinMain() { + try { + 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 new file mode 100644 index 0000000..53ceba0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Run5_lockRein.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.synchronize.example5; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P67 + * synchronized锁重入,支持继承 + */ +public class Run5_lockRein { + public static void main(String[] args) { + Thread t = new Thread() { + @Override + public void run() { + Sub sub = new Sub(); + sub.operateIinSub(); + } + }; + t.start(); + + } + +} + +/* +输出: +sub print i=9 +main print i=8 +sub print i=7 +main print i=6 +sub print i=5 +main print i=4 +sub print i=3 +main print i=2 +sub print i=1 +main print i=0 + */ 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 new file mode 100644 index 0000000..a950354 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example5/Sub.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.synchronize.example5; + +/** + * Created by Brian on 2016/4/12. + */ +public class Sub extends Main { + synchronized public void operateIinSub() { + try { + while (i > 0) { + i--; + System.out.println("sub print i=" + i); + Thread.sleep(100); + this.operateIinMain(); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} 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 new file mode 100644 index 0000000..8ca51b0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Run6_exception.java @@ -0,0 +1,67 @@ +package com.brianway.learning.java.multithread.synchronize.example6; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P68 + * 出现异常,锁自动释放 + */ +public class Run6_exception { + public static void main(String[] args) { + + try { + Service service = new Service(); + ThreadA a = new ThreadA("a", service); + a.start(); + Thread.sleep(500); + ThreadB b = new ThreadB("b", service); + b.start(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } +} + + +/* +输出: +ThreadName=a run beginTime=1460455843215 +Exception in thread "a" java.lang.NumberFormatException: For input string: "a" +ThreadName=a run exceptionTime=1460455843719 + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) +Thread b run Time=1460455843719 + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.synchronize.example6.Service.testMethod(Service.java:15) + at com.brianway.learning.java.multithread.synchronize.example6.ThreadA.run(ThreadA.java:16) + +--------------- + +ThreadName=a run beginTime=1460455874981 +ThreadName=a run exceptionTime=1460455875079 +Exception in thread "a" java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.synchronize.example6.Service.testMethod(Service.java:15) + at com.brianway.learning.java.multithread.synchronize.example6.ThreadA.run(ThreadA.java:16) +Thread b run Time=1460455875480 + + + +--------- + + +ThreadName=a run beginTime=1460455887793 +Exception in thread "a" java.lang.NumberFormatException: For input string: "a" + at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) + at java.lang.Integer.parseInt(Integer.java:580) + at java.lang.Integer.parseInt(Integer.java:615) + at com.brianway.learning.java.multithread.synchronize.example6.Service.testMethod(Service.java:15) + at com.brianway.learning.java.multithread.synchronize.example6.ThreadA.run(ThreadA.java:16) +ThreadName=a run exceptionTime=1460455887945 +Thread b run Time=1460455888293 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..d33d095 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/Service.java @@ -0,0 +1,22 @@ +package com.brianway.learning.java.multithread.synchronize.example6; + +/** + * 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()); + + 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()); + Integer.parseInt("a"); + } + } + } 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 new file mode 100644 index 0000000..d3ecf75 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadA.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example6; + +/** + * Created by Brian on 2016/4/12. + */ +public class ThreadA extends Thread { + private Service service; + + public ThreadA(String name, Service service) { + super(name); + this.service = service; + } + + @Override + public void run() { + service.testMethod(); + } +} 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 new file mode 100644 index 0000000..8c5d51e --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example6/ThreadB.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example6; + +/** + * Created by Brian on 2016/4/12. + */ +public class ThreadB extends Thread { + private Service service; + + public ThreadB(String name, Service service) { + super(name); + this.service = service; + } + + @Override + public void run() { + service.testMethod(); + } +} 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 new file mode 100644 index 0000000..13bd444 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Main.java @@ -0,0 +1,16 @@ +package com.brianway.learning.java.multithread.synchronize.example7; + +/** + * Created by Brian on 2016/4/12. + */ +public class Main { + synchronized public void testMethod() { + try { + 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()); + } 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 new file mode 100644 index 0000000..a3b3955 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/MyThread.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example7; + +/** + * Created by Brian on 2016/4/12. + */ +public class MyThread extends Thread { + private Sub sub; + + public MyThread(Sub sub) { + super(); + this.sub = sub; + } + + @Override + public void run() { + sub.testMethod(); + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Run7_synNotExtends.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Run7_synNotExtends.java new file mode 100644 index 0000000..122ec56 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Run7_synNotExtends.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.multithread.synchronize.example7; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P71 + * 同步不具继承性 + */ +public class Run7_synNotExtends { + public static void main(String[] args) { + Sub sub = new Sub(); + MyThread a = new MyThread(sub); + a.setName("A"); + a.start(); + MyThread b = new MyThread(sub); + b.setName("B"); + b.start(); + } +} + +/* +Sub的testMethod不加synchronized +输出: +threadName= A in sub 下一步 sleep begin time =1460457287103 +threadName= B in sub 下一步 sleep begin time =1460457287103 +threadName= A in sub 下一步 sleep end time =1460457289103 +threadName= B in sub 下一步 sleep end time =1460457289103 +threadName= A in main 下一步 sleep begin time =1460457289103 +threadName= A in main 下一步 sleep end time =1460457291103 +threadName= B in main 下一步 sleep begin time =1460457291103 +threadName= B in main 下一步 sleep end time =1460457293103 + +-------------------- +Sub的testMethod加synchronized +输出: +threadName= A in sub 下一步 sleep begin time =1460457463877 +threadName= A in sub 下一步 sleep end time =1460457465878 +threadName= A in main 下一步 sleep begin time =1460457465878 +threadName= A in main 下一步 sleep end time =1460457470879 +threadName= B in sub 下一步 sleep begin time =1460457470879 +threadName= B in sub 下一步 sleep end time =1460457472879 +threadName= B in main 下一步 sleep begin time =1460457472879 +threadName= B in main 下一步 sleep end time =1460457477879 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..d8f2d9f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example7/Sub.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example7; + +/** + * Created by Brian on 2016/4/12. + */ +public class Sub extends Main { + //synchronized + public void testMethod() { + try { + 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()); + super.testMethod(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/CommonUtils.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/CommonUtils.java new file mode 100644 index 0000000..54592f7 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/CommonUtils.java @@ -0,0 +1,11 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ +public class CommonUtils { + public static long beginTime1; + public static long endTime1; + public static long beginTime2; + public static long endTime2; +} 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 new file mode 100644 index 0000000..2cbbc78 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadA.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ +public class MyThreadA extends Thread { + private 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(); + taskA.doLongTimeTask(); + CommonUtils.endTime1 = System.currentTimeMillis(); + } else if (this.getName().equals("b")) { + CommonUtils.beginTime2 = System.currentTimeMillis(); + taskA.doLongTimeTask(); + CommonUtils.endTime2 = System.currentTimeMillis(); + } 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 new file mode 100644 index 0000000..5f77112 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/MyThreadB.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ +public class MyThreadB extends Thread { + private 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(); + taskB.doLongTimeTask(); + CommonUtils.endTime1 = System.currentTimeMillis(); + } else if (this.getName().equals("d")) { + CommonUtils.beginTime2 = System.currentTimeMillis(); + taskB.doLongTimeTask(); + CommonUtils.endTime2 = System.currentTimeMillis(); + } 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 new file mode 100644 index 0000000..68195e1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized01.java @@ -0,0 +1,48 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P72 + * synchronized方法的弊端 + */ +public class Run8_synchronized01 { + public static void main(String[] args) { + TaskA taskA = new TaskA(); + MyThreadA thread1 = new MyThreadA(taskA); + thread1.setName("a"); + thread1.start(); + + MyThreadA thread2 = new MyThreadA(taskA); + thread2.setName("b"); + thread2.start(); + + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + 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); + } + +} + + +/* +输出: +begin task +长时间处理任务后从远程返回的值1 threadName=a +长时间处理任务后从远程返回的值2 threadName=a +end task +begin task +长时间处理任务后从远程返回的值1 threadName=b +长时间处理任务后从远程返回的值2 threadName=b +end task +耗时:6 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..6f2dde5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/Run8_synchronized02.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P76 + * 同步代码块解决同步方法的弊端 + * TODO 但输出并不是两个c,两个d,原因? + */ +public class Run8_synchronized02 { + public static void main(String[] args) { + TaskB taskB = new TaskB(); + MyThreadB thread1 = new MyThreadB(taskB); + thread1.setName("c"); + thread1.start(); + + MyThreadB thread2 = new MyThreadB(taskB); + thread2.setName("d"); + thread2.start(); + + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + 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); + } + +} + +/* +输出: +begin task +begin task +长时间处理任务后从远程返回的值1 threadName=c +长时间处理任务后从远程返回的值2 threadName=d +end task +长时间处理任务后从远程返回的值1 threadName=d +长时间处理任务后从远程返回的值2 threadName=d +end task +耗时:3 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..a2bdead --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskA.java @@ -0,0 +1,23 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ +public class TaskA { + private String getData1; + private String getData2; + + 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(); + System.out.println(getData1); + System.out.println(getData2); + System.out.println("end task"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} 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 new file mode 100644 index 0000000..5cfc9b4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example8/TaskB.java @@ -0,0 +1,30 @@ +package com.brianway.learning.java.multithread.synchronize.example8; + +/** + * Created by Brian on 2016/4/12. + */ +public class TaskB { + private String getData1; + private String getData2; + + 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) { + //System.out.println("切换到线程begin:"+Thread.currentThread().getName()); + getData1 = privateGetData1; + getData2 = privateGetData2; + //System.out.println("切换到线程end:"+Thread.currentThread().getName()); + } + + System.out.println(getData1); + System.out.println(getData2); + System.out.println("end task"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject.java b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject.java new file mode 100644 index 0000000..4993a22 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject.java @@ -0,0 +1,7 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ +public class MyObject { +} 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 new file mode 100644 index 0000000..c30a6c3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject1.java @@ -0,0 +1,12 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * 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()); + System.out.println("*******************"); + 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 new file mode 100644 index 0000000..c73a380 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyObject2.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * 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()); + System.out.println("*******************"); + 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 new file mode 100644 index 0000000..989e92a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/MyThread.java @@ -0,0 +1,21 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ +public class MyThread extends Thread { + private Service service; + private MyObject object; + + public MyThread(Service service, MyObject object) { + super(); + this.object = object; + this.service = service; + } + + @Override + public void run() { + super.run(); + service.testMethod1(object); + } +} 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 new file mode 100644 index 0000000..b5994f4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01.java @@ -0,0 +1,37 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P91 + * synchronized(非this对象x)的三个结论 + * 1)当多个线程同时执行synchronized(x){}同步代码块时呈现效果 + * 2)当其他线程执行x对象中synchronized同步方法时呈同步效果 + * 3)当其他线程执行x对象里面的synchronized(this)代码块时,也呈现同步效果 + * 验证结论1: + * 当多个线程同时执行synchronized(x){}同步代码块时呈现效果 + */ +public class Run9_synchronized01 { + public static void main(String[] args) { + Service service = new Service(); + MyObject object = new MyObject(); + + MyThread a = new MyThread(service, object); + a.setName("a"); + a.start(); + MyThread b = new MyThread(service, object); + b.setName("b"); + b.start(); + + } +} + +/* +输出: +testMethod1 ____getLock time=1460467206978 run ThreadName=a +testMethod1 releaseLock time=1460467208978 run ThreadName=a +testMethod1 ____getLock time=1460467208978 run ThreadName=b +testMethod1 releaseLock time=1460467210978 run ThreadName=b + */ \ No newline at end of file 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 new file mode 100644 index 0000000..98d311b --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized01_twoObjects.java @@ -0,0 +1,34 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P93 + * 不同的“对象监视器” + */ +public class Run9_synchronized01_twoObjects { + public static void main(String[] args) { + Service service = new Service(); + MyObject object1 = new MyObject(); + MyObject object2 = new MyObject(); + + MyThread a = new MyThread(service, object1); + a.setName("a"); + a.start(); + MyThread b = new MyThread(service, object2); + b.setName("b"); + b.start(); + + } +} + +/* +输出: +testMethod1 ____getLock time=1460467346174 run ThreadName=a +testMethod1 ____getLock time=1460467346174 run ThreadName=b +testMethod1 releaseLock time=1460467348174 run ThreadName=a +testMethod1 releaseLock time=1460467348174 run ThreadName=b + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..9db4ea8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized02.java @@ -0,0 +1,41 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P93 + * synchronized(非this对象x)的三个结论 + * 1)当多个线程同时执行synchronized(x){}同步代码块时呈现效果 + * 2)当其他线程执行x对象中synchronized同步方法时呈同步效果 + * 3)当其他线程执行x对象里面的synchronized(this)代码块时,也呈现同步效果 + * 验证结论2: + * 当其他线程执行x对象中synchronized同步方法时呈同步效果 + */ +public class Run9_synchronized02 { + public static void main(String[] args) { + Service service = new Service(); + MyObject1 object1 = new MyObject1(); + + MyThread a = new MyThread(service, object1); + a.setName("a"); + a.start(); + Thread1 b = new Thread1(object1); + b.setName("b"); + b.start(); + + } + +} + + +/* +输出: +testMethod1 ____getLock time=1460468427929 run ThreadName=a +testMethod1 releaseLock time=1460468429930 run ThreadName=a +speedPrintString ____getLock time=1460468429930 run ThreadName=b +******************* +speedPrintString releaseLock time=1460468429930 run ThreadName=b + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..26827c3 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Run9_synchronized03.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ + +/** + * P95 + * synchronized(非this对象x)的三个结论 + * 1)当多个线程同时执行synchronized(x){}同步代码块时呈现效果 + * 2)当其他线程执行x对象中synchronized同步方法时呈同步效果 + * 3)当其他线程执行x对象里面的synchronized(this)代码块时,也呈现同步效果 + * 验证结论1: + * 当其他线程执行x对象里面的ynchronized(this)代码块时,也呈现同步效果 + */ + +public class Run9_synchronized03 { + public static void main(String[] args) { + Service service = new Service(); + MyObject2 object2 = new MyObject2(); + + MyThread a = new MyThread(service, object2); + a.setName("a"); + a.start(); + Thread2 b = new Thread2(object2); + b.setName("b"); + b.start(); + + } + +} + + +/* +输出: +testMethod1 ____getLock time=1460468687415 run ThreadName=a +testMethod1 releaseLock time=1460468689415 run ThreadName=a +speedPrintString ____getLock time=1460468689415 run ThreadName=b +******************* +speedPrintString releaseLock time=1460468689415 run ThreadName=b + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..507a336 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Service.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ +public class Service { + public void testMethod1(MyObject object) { + synchronized (object) { + try { + 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()); + } 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 new file mode 100644 index 0000000..bc4be32 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread1.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ +public class Thread1 extends Thread { + private MyObject1 object1; + + public Thread1(MyObject1 object1) { + this.object1 = object1; + } + + @Override + public void run() { + super.run(); + object1.speedPrintString(); + } +} 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 new file mode 100644 index 0000000..34855b4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/synchronize/example9/Thread2.java @@ -0,0 +1,18 @@ +package com.brianway.learning.java.multithread.synchronize.example9; + +/** + * Created by Brian on 2016/4/12. + */ +public class Thread2 extends Thread { + private MyObject2 object2; + + public Thread2(MyObject2 object2) { + this.object2 = object2; + } + + @Override + public void run() { + super.run(); + object2.speedPrintString(); + } +} 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 new file mode 100644 index 0000000..12c783c --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/MyTask.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class MyTask extends TimerTask { + @Override + public void run() { + 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 new file mode 100644 index 0000000..e269b2f --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer1.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P242 + * schedule(TimerTask task, Date time)测试,在未来执行的效果 + * Timer的构造方法会新启一个线程,且非守护线程 + */ +public class Run1_timer1 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 5); + Date runDate = calendar.getTime(); + + MyTask task = new MyTask(); + Timer timer = new Timer(); + timer.schedule(task, runDate); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:10:14 CST 2016 +任务执行了,时间为:Fri Apr 15 22:10:19 CST 2016 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..8f77089 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer2.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P243 + * schedule(TimerTask task, Date time)测试,在未来执行的效果 + * Timer的构造方法会新启一个守护线程 + * 迅速结束,task任务未被执行 + */ +public class Run1_timer2 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 5); + Date runDate = calendar.getTime(); + + MyTask task = new MyTask(); + Timer timer = new Timer(true);//守护线程 + timer.schedule(task, runDate); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:12:28 CST 2016 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..5163053 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer3.java @@ -0,0 +1,33 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P244 + * schedule(TimerTask task, Date time)测试,提前运行的效果 + */ +public class Run1_timer3 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 10); + Date runDate = calendar.getTime(); + System.out.println("计划时间为:" + runDate); + MyTask task = new MyTask(); + Timer timer = new Timer(); + timer.schedule(task, runDate); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:15:40 CST 2016 +计划时间为:Fri Apr 15 22:15:30 CST 2016 +任务执行了,时间为:Fri Apr 15 22:15:40 CST 2016 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..a686757 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer4.java @@ -0,0 +1,43 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P245 + * schedule(TimerTask task, Date time)测试,多个TimerTask任务及延时 + */ +public class Run1_timer4 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 5); + Date runDate = calendar.getTime(); + System.out.println("计划时间为:" + runDate); + + Calendar calendar2 = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 10); + Date runDate2 = calendar2.getTime(); + System.out.println("计划时间为:" + runDate2); + + MyTask task1 = new MyTask(); + MyTask task2 = new MyTask(); + Timer timer = new Timer(); + timer.schedule(task1, runDate); + timer.schedule(task2, runDate); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:24:08 CST 2016 +计划时间为:Fri Apr 15 22:24:13 CST 2016 +计划时间为:Fri Apr 15 22:24:08 CST 2016 +任务执行了,时间为:Fri Apr 15 22:24:13 CST 2016 +任务执行了,时间为:Fri Apr 15 22:24:13 CST 2016 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..ff7c9bc --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/Run1_timer5.java @@ -0,0 +1,45 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P246 + * schedule(TimerTask task, Date time)测试,多个TimerTask任务及延时 + * 队列的方式,一个一个被顺序执行,前面一个耗时长则后面的任务被延后 + */ +public class Run1_timer5 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + System.out.println("A计划时间为:" + runDate); + + Calendar calendar2 = Calendar.getInstance(); + calendar2.add(Calendar.SECOND, 5); + Date runDate2 = calendar2.getTime(); + 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); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:39:30 CST 2016 +A计划时间为:Fri Apr 15 22:39:30 CST 2016 +B计划时间为:Fri Apr 15 22:39:35 CST 2016 +A begin timer=Fri Apr 15 22:39:30 CST 2016 +A end timer=Fri Apr 15 22:39:40 CST 2016 +B begin timer=Fri Apr 15 22:39:40 CST 2016 +B end timer=Fri Apr 15 22:39:40 CST 2016 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..9b142f8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskA.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class TaskA extends TimerTask { + @Override + public void run() { + try { + System.out.println("A begin timer=" + new Date()); + Thread.sleep(10000); + 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 new file mode 100644 index 0000000..6997f42 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example1/TaskB.java @@ -0,0 +1,15 @@ +package com.brianway.learning.java.multithread.timer.example1; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +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()); + } +} 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 new file mode 100644 index 0000000..c087214 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/MyTask.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.timer.example2; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class MyTask extends TimerTask { + @Override + public void run() { + 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 new file mode 100644 index 0000000..a348ba9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period1.java @@ -0,0 +1,38 @@ +package com.brianway.learning.java.multithread.timer.example2; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P247 + * schedule(TimerTask task, long delay, long period) 测试,在未来执行的效果 + */ +public class Run2_period1 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 10); + Date runDate = calendar.getTime(); + System.out.println("计划时间为:" + runDate); + + MyTask task = new MyTask(); + Timer timer = new Timer(); + timer.schedule(task, runDate, 4000); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:40:46 CST 2016 +计划时间为:Fri Apr 15 22:40:56 CST 2016 +任务执行了,时间为:Fri Apr 15 22:40:56 CST 2016 +任务执行了,时间为:Fri Apr 15 22:41:00 CST 2016 +任务执行了,时间为:Fri Apr 15 22:41:04 CST 2016 + +(一直执行,后面省略) + */ \ No newline at end of file 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 new file mode 100644 index 0000000..64c6ea4 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period2.java @@ -0,0 +1,39 @@ +package com.brianway.learning.java.multithread.timer.example2; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P247 + * schedule(TimerTask task, long delay, long period) 测试,提前运行的效果 + */ +public class Run2_period2 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 10); + Date runDate = calendar.getTime(); + System.out.println("计划时间为:" + runDate); + + MyTask task = new MyTask(); + Timer timer = new Timer(); + timer.schedule(task, runDate, 4000); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:42:32 CST 2016 +计划时间为:Fri Apr 15 22:42:22 CST 2016 +任务执行了,时间为:Fri Apr 15 22:42:32 CST 2016 +任务执行了,时间为:Fri Apr 15 22:42:36 CST 2016 +任务执行了,时间为:Fri Apr 15 22:42:40 CST 2016 +任务执行了,时间为:Fri Apr 15 22:42:44 CST 2016 + +(一直执行,后面省略) + */ \ No newline at end of file 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 new file mode 100644 index 0000000..a4fb9b0 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/Run2_period3.java @@ -0,0 +1,42 @@ +package com.brianway.learning.java.multithread.timer.example2; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P248 + * schedule(TimerTask task, long delay, long period) 测试,任务执行时间被延时 + */ +public class Run2_period3 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.SECOND, 10); + Date runDate = calendar.getTime(); + System.out.println("计划时间为:" + runDate); + + TaskA task = new TaskA(); + Timer timer = new Timer(); + timer.schedule(task, runDate, 3000); + } +} + +/* +输出: +当前时间为:Fri Apr 15 22:44:47 CST 2016 +计划时间为:Fri Apr 15 22:44:57 CST 2016 +A begin timer=Fri Apr 15 22:44:57 CST 2016 +A end timer=Fri Apr 15 22:45:02 CST 2016 +A begin timer=Fri Apr 15 22:45:02 CST 2016 +A end timer=Fri Apr 15 22:45:07 CST 2016 +A begin timer=Fri Apr 15 22:45:07 CST 2016 +A end timer=Fri Apr 15 22:45:12 CST 2016 +A begin timer=Fri Apr 15 22:45:12 CST 2016 + +(一直执行,后面省略) + */ \ No newline at end of file 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 new file mode 100644 index 0000000..bc5d902 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example2/TaskA.java @@ -0,0 +1,20 @@ +package com.brianway.learning.java.multithread.timer.example2; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class TaskA extends TimerTask { + @Override + public void run() { + try { + System.out.println("A begin timer=" + new Date()); + Thread.sleep(5000); + 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 new file mode 100644 index 0000000..d539ada --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/MyTask.java @@ -0,0 +1,19 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.TimerTask; + +/** + * Created by brian on 2016/4/15. + */ +public class MyTask extends TimerTask { + private int i; + + public MyTask(int i) { + this.i = i; + } + + @Override + public void run() { + 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 new file mode 100644 index 0000000..b6b75d9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel1.java @@ -0,0 +1,44 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P249 + * TimerTask类的cancel()方法 + * 将自身从任务队列移除,其他任务不受影响 + */ +public class Run3_cancel1 { + public static void main(String[] args) { + System.out.println("当前时间为:" + new Date()); + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + System.out.println("计划时间为:" + runDate); + + TaskA task1 = new TaskA(); + TaskB task2 = new TaskB(); + Timer timer = new Timer(); + timer.schedule(task1, runDate, 4000); + timer.schedule(task2, runDate, 4000); + + } +} + +/* +输出: +当前时间为:Fri Apr 15 23:41:22 CST 2016 +计划时间为:Fri Apr 15 23:41:22 CST 2016 +A run timer=Fri Apr 15 23:41:22 CST 2016 +A任务自己移除自己 +B run timer=Fri Apr 15 23:41:22 CST 2016 +B run timer=Fri Apr 15 23:41:26 CST 2016 +B run timer=Fri Apr 15 23:41:30 CST 2016 + + +(一直执行,后面省略) + */ \ No newline at end of file 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 new file mode 100644 index 0000000..466be39 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel2.java @@ -0,0 +1,48 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P250 + * Timer类的cancel()方法 + * 全部任务被清除,且进程被销毁 + */ +public class Run3_cancel2 { + 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); + + TaskA2 task1 = new TaskA2(); + TaskB2 task2 = new TaskB2(); + Timer timer = new Timer(); + timer.schedule(task1, runDate, 2000); + timer.schedule(task2, runDate, 2000); + Thread.sleep(10000); + timer.cancel(); + } +} + +/* +输出: +当前时间为:Fri Apr 15 23:49:29 CST 2016 +计划时间为:Fri Apr 15 23:49:29 CST 2016 +A run timer=Fri Apr 15 23:49:29 CST 2016 +B run timer=Fri Apr 15 23:49:29 CST 2016 +A run timer=Fri Apr 15 23:49:31 CST 2016 +B run timer=Fri Apr 15 23:49:31 CST 2016 +A run timer=Fri Apr 15 23:49:33 CST 2016 +B run timer=Fri Apr 15 23:49:33 CST 2016 +B run timer=Fri Apr 15 23:49:35 CST 2016 +A run timer=Fri Apr 15 23:49:35 CST 2016 +A run timer=Fri Apr 15 23:49:37 CST 2016 +B run timer=Fri Apr 15 23:49:37 CST 2016 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..df103e1 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/Run3_cancel3.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; + +/** + * Created by Brian on 2016/4/15. + */ + +/** + * P252 + * Timer类的cancel()方法 + * 有时不一定会停止计划任务,(见源码,queue锁) + */ +public class Run3_cancel3 { + public static void main(String[] args) throws InterruptedException { + int i = 0; + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + + while (true) { + i++; + Timer timer = new Timer(); + MyTask task = new MyTask(i); + timer.schedule(task, runDate); + timer.cancel(); + } + + } +} + +/* +输出: +第1次没有被cancel取消 +第44674次没有被cancel取消 +第44676次没有被cancel取消 +第44678次没有被cancel取消 +第44682次没有被cancel取消 +第44684次没有被cancel取消 +第44686次没有被cancel取消 +第44688次没有被cancel取消 +第44697次没有被cancel取消 +第44702次没有被cancel取消 +第44706次没有被cancel取消 +第67967次没有被cancel取消 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..f93c6bb --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA.java @@ -0,0 +1,16 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class TaskA extends TimerTask { + @Override + public void run() { + 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 new file mode 100644 index 0000000..430deed --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskA2.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class TaskA2 extends TimerTask { + @Override + public void run() { + 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 new file mode 100644 index 0000000..996dbb5 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by brian on 2016/4/15. + */ +public class TaskB extends TimerTask { + @Override + public void run() { + 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 new file mode 100644 index 0000000..63ad2aa --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example3/TaskB2.java @@ -0,0 +1,14 @@ +package com.brianway.learning.java.multithread.timer.example3; + +import java.util.Date; +import java.util.TimerTask; + +/** + * Created by Brian on 2016/4/15. + */ +public class TaskB2 extends TimerTask { + @Override + public void run() { + 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 new file mode 100644 index 0000000..feeeca8 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule1.java @@ -0,0 +1,36 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P252 + * schedule(TimerTask task, long delay)方法 + */ +public class Run4_schedule1 { + static public class MyTask extends TimerTask { + @Override + public void run() { + 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); + } +} + +/* +输出: +当前时间:Sat Apr 16 00:00:22 CST 2016 +运行了!时间为:Sat Apr 16 00:00:29 CST 2016 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..a841364 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule2.java @@ -0,0 +1,39 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P253 + * schedule(TimerTask task, long delay, long period)方法 + */ +public class Run4_schedule2 { + static public class MyTask extends TimerTask { + @Override + public void run() { + 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); + } +} + +/* +输出: +当前时间:Sat Apr 16 00:01:34 CST 2016 +运行了!时间为:Sat Apr 16 00:01:36 CST 2016 +运行了!时间为:Sat Apr 16 00:01:37 CST 2016 +运行了!时间为:Sat Apr 16 00:01:38 CST 2016 +运行了!时间为:Sat Apr 16 00:01:39 CST 2016 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..337e598 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule3.java @@ -0,0 +1,57 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P254 + * schedule(TimerTask task, Date firstTime, long period) 方法 + * Date类型 + * 不延时的情况下,若执行任务未被延时,下次执行任务的开始时间是上一次任务的开始时间加上period + */ +public class Run4_schedule3 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(1000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + Timer timer = new Timer(); + timer.schedule(task, runDate, 3000); + } +} + +/* +输出: +begin timer=1460736286532 +end timer=1460736287533 +begin timer=1460736289532 +end timer=1460736290532 +begin timer=1460736292536 +end timer=1460736293536 +begin timer=1460736295536 +end timer=1460736296536 +begin timer=1460736298536 +end timer=1460736299536 +begin timer=1460736301536 +end timer=1460736302536 + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..2ea64c9 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule4.java @@ -0,0 +1,50 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Timer; +import java.util.TimerTask; + +/** + * P255 + * schedule(TimerTask task, long delay, long period)方法 + * long类型 + * 不延时的情况下,若执行任务未被延时,第一次执行是任务开始+delay,下次执行任务的开始时间是上一次任务的开始时间加上period + */ +public class Run4_schedule4 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(1000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + System.out.println("当前时间:" + System.currentTimeMillis()); + Timer timer = new Timer(); + timer.schedule(task, 3000, 4000); + } +} + +/* +输出: +当前时间:1460736721660 +begin timer=1460736724662 +end timer=1460736725662 +begin timer=1460736728662 +end timer=1460736729662 +begin timer=1460736732662 +end timer=1460736733662 +begin timer=1460736736662 +end timer=1460736737662 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..a01c942 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule5.java @@ -0,0 +1,52 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P255 + * schedule(TimerTask task, Date firstTime, long period) 方法 + * Date类型 + * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 + */ +public class Run4_schedule5 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(5000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + Timer timer = new Timer(); + timer.schedule(task, runDate, 2000); + } +} + +/* +输出: +begin timer=1460738337277 +end timer=1460738342278 +begin timer=1460738342278 +end timer=1460738347278 +begin timer=1460738347278 +end timer=1460738352278 +begin timer=1460738352278 + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..6414872 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule6.java @@ -0,0 +1,48 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Timer; +import java.util.TimerTask; + +/** + * P256 + * schedule(TimerTask task, long delay, long period)方法 + * long类型 + * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 + */ +public class Run4_schedule6 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(5000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + System.out.println("当前时间:" + System.currentTimeMillis()); + Timer timer = new Timer(); + timer.schedule(task, 3000, 2000); + } +} + +/* +输出: +当前时间:1460737882848 +begin timer=1460737885849 +end timer=1460737890849 +begin timer=1460737890849 +end timer=1460737895849 +begin timer=1460737895849 +end timer=1460737900850 +begin timer=1460737900850 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..1dac553 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate1.java @@ -0,0 +1,51 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P257 + * scheduleAtFixedRate(TimerTask task, Date firstTime,long period)方法 + * Date类型 + * 不延时的情况下,若执行任务未被延时,下次执行任务的开始时间是上一次任务的开始时间加上period + */ +public class Run4_scheduleAtFixedRate1 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(1000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + Timer timer = new Timer(); + timer.scheduleAtFixedRate(task, runDate, 3000); + } +} + +/* +输出: +begin timer=1460738424663 +end timer=1460738425663 +begin timer=1460738427636 +end timer=1460738428636 +begin timer=1460738430635 +end timer=1460738431635 + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..8b1ba32 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate2.java @@ -0,0 +1,49 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Timer; +import java.util.TimerTask; + +/** + * P258 + * scheduleAtFixedRate(TimerTask task, long delay, long period)方法 + * long类型 + * 不延时的情况下,若执行任务未被延时,第一次执行是任务开始+delay,下次执行任务的开始时间是上一次任务的开始时间加上period + */ +public class Run4_scheduleAtFixedRate2 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(1000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + System.out.println("当前时间:" + System.currentTimeMillis()); + Timer timer = new Timer(); + timer.scheduleAtFixedRate(task, 3000, 4000); + } +} + +/* +输出: +当前时间:1460738574939 +begin timer=1460738577940 +end timer=1460738578940 +begin timer=1460738581940 +end timer=1460738582940 +begin timer=1460738585940 +end timer=1460738586940 + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..b01be92 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate3.java @@ -0,0 +1,52 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P258 + * scheduleAtFixedRate(TimerTask task, Date firstTime, long period) 方法 + * Date类型 + * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 + */ +public class Run4_scheduleAtFixedRate3 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(5000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + Calendar calendar = Calendar.getInstance(); + Date runDate = calendar.getTime(); + Timer timer = new Timer(); + timer.scheduleAtFixedRate(task, runDate, 2000); + } +} + +/* +输出: +begin timer=1460738658244 +end timer=1460738663246 +begin timer=1460738663246 +end timer=1460738668247 +begin timer=1460738668247 +end timer=1460738673247 +begin timer=1460738673247 + + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..d525115 --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_scheduleAtFixedRate4.java @@ -0,0 +1,47 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Timer; +import java.util.TimerTask; + +/** + * P259 + * scheduleAtFixedRate(TimerTask task, long delay, long period)方法 + * long类型 + * 在延时的情况下,若执行任务被延时,下次执行任务的开始时间是上一次任务的开始时间作为参考点 + */ +public class Run4_scheduleAtFixedRate4 { + static public class MyTask extends TimerTask { + @Override + public void run() { + try { + System.out.println("begin timer=" + System.currentTimeMillis()); + Thread.sleep(5000); + System.out.println("end timer=" + System.currentTimeMillis()); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + MyTask task = new MyTask(); + System.out.println("当前时间:" + System.currentTimeMillis()); + Timer timer = new Timer(); + timer.scheduleAtFixedRate(task, 3000, 2000); + } +} + +/* +输出: +当前时间:1460738720674 +begin timer=1460738723676 +end timer=1460738728676 +begin timer=1460738728676 +end timer=1460738733676 +begin timer=1460738733676 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..2bf97ad --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_1.java @@ -0,0 +1,50 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P260 + * schedule不具有追赶执行性 + */ +public class Run4_schedule_vs_scheduleAtFixedRate_1 { + static public class MyTask extends TimerTask { + @Override + public void run() { + 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()); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 20); + Date runDate = calendar.getTime(); + System.out.println("计划执行时间:" + runDate); + Timer timer = new Timer(); + timer.schedule(task, runDate, 2000); + } +} + +/* +输出: +现在执行时间:Sat Apr 16 00:51:36 CST 2016 +计划执行时间:Sat Apr 16 00:51:16 CST 2016 +begin timer=Sat Apr 16 00:51:36 CST 2016 +end timer=Sat Apr 16 00:51:36 CST 2016 +begin timer=Sat Apr 16 00:51:38 CST 2016 +end timer=Sat Apr 16 00:51:38 CST 2016 +begin timer=Sat Apr 16 00:51:40 CST 2016 +end timer=Sat Apr 16 00:51:40 CST 2016 +begin timer=Sat Apr 16 00:51:42 CST 2016 +end timer=Sat Apr 16 00:51:42 CST 2016 + + */ \ No newline at end of file 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 new file mode 100644 index 0000000..a493c8a --- /dev/null +++ b/java-multithread/src/main/java/com/brianway/learning/java/multithread/timer/example4/Run4_schedule_vs_scheduleAtFixedRate_2.java @@ -0,0 +1,69 @@ +package com.brianway.learning.java.multithread.timer.example4; + +/** + * Created by brian on 2016/4/15. + */ + +import java.util.Calendar; +import java.util.Date; +import java.util.Timer; +import java.util.TimerTask; + +/** + * P261 + * scheduleAtFixedRate具有追赶执行性 + */ +public class Run4_schedule_vs_scheduleAtFixedRate_2 { + static public class MyTask extends TimerTask { + @Override + public void run() { + 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()); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) - 20); + Date runDate = calendar.getTime(); + System.out.println("计划执行时间:" + runDate); + Timer timer = new Timer(); + timer.scheduleAtFixedRate(task, runDate, 2000); + } +} + +/* +输出: +现在执行时间:Sat Apr 16 00:54:46 CST 2016 +计划执行时间:Sat Apr 16 00:54:26 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:46 CST 2016 +end timer=Sat Apr 16 00:54:46 CST 2016 +begin timer=Sat Apr 16 00:54:48 CST 2016 +end timer=Sat Apr 16 00:54:48 CST 2016 +begin timer=Sat Apr 16 00:54:50 CST 2016 +end timer=Sat Apr 16 00:54:50 CST 2016 +begin timer=Sat Apr 16 00:54:52 CST 2016 +end timer=Sat Apr 16 00:54:52 CST 2016 + */ \ No newline at end of file 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 new file mode 100644 index 0000000..5965258 --- /dev/null +++ b/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + com.brianway.learning.java + java-learning + pom + Java Learning + 1.0-SNAPSHOT + + + UTF-8 + UTF-8 + 1.8 + 1.8 + 4.13.1 + + + + Java学习笔记,主要是对一些基础特性和编程细节进行总结整理。包含示例源码,涉及反射,代理,集合,IO,多线程等。 + + https://github.com/brianway/java-learning/ + + + + brianway + Chuyang Wei + weichuyang@163.com + + + + + scm:git:git@github.com:brianway/java-learning.git + scm:git:git@github.com:brianway/java-learning.git + git@github.com:brianway/java-learning.git + HEAD + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + java-multithread + java-base + java-container + java-io + java8 + java-jvm + + + + + + junit + junit + ${junit.version} + test + + + + + \ No newline at end of file