From 6fb6f56f6b472ba145381e4ce1aa1b7168c0f684 Mon Sep 17 00:00:00 2001 From: tangjia Date: Thu, 28 Jul 2016 18:53:35 +0800 Subject: [PATCH 01/17] Site updated: 2016-07-28 18:53:35 --- .../index.html | 4 ++-- .../index.html" | 4 ++-- 2016/07/20/Contaniner/index.html | 2 +- 2016/07/20/hello-world/index.html | 4 ++-- .../20/\345\223\210\345\223\210/index.html" | 2 +- .../index.html" | 22 +++++++++++++++++++ about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/04/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- .../index.html" | 2 +- 15 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 "2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index c50586c..d04eca8 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

+Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

###1. Why should we use Servlet
For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

###2. How does it process requests
It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

@@ -10,4 +10,4 @@

Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

-
Aktie
第一篇
\ No newline at end of file +
Share
第一篇
\ No newline at end of file diff --git "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" index 29f1ac2..032fe55 100644 --- "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" +++ "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" @@ -1,4 +1,4 @@ -第一篇 | 唐佳写字的地方
\ No newline at end of file diff --git a/2016/07/20/Contaniner/index.html b/2016/07/20/Contaniner/index.html index 2e5fe6d..85346aa 100644 --- a/2016/07/20/Contaniner/index.html +++ b/2016/07/20/Contaniner/index.html @@ -1 +1 @@ -Contaniner | 唐佳写字的地方
\ No newline at end of file +Contaniner | 唐佳写字的地方
\ No newline at end of file diff --git a/2016/07/20/hello-world/index.html b/2016/07/20/hello-world/index.html index f1841d2..923632e 100644 --- a/2016/07/20/hello-world/index.html +++ b/2016/07/20/hello-world/index.html @@ -1,4 +1,4 @@ -Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

+Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server
@@ -7,4 +7,4 @@

Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

-
Aktie
Contaniner
\ No newline at end of file +
Share
Contaniner
\ No newline at end of file diff --git "a/2016/07/20/\345\223\210\345\223\210/index.html" "b/2016/07/20/\345\223\210\345\223\210/index.html" index bf03c7b..142cde8 100644 --- "a/2016/07/20/\345\223\210\345\223\210/index.html" +++ "b/2016/07/20/\345\223\210\345\223\210/index.html" @@ -1 +1 @@ -哈哈 | 唐佳写字的地方
\ No newline at end of file +哈哈 | 唐佳写字的地方
\ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" new file mode 100644 index 0000000..2364597 --- /dev/null +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -0,0 +1,22 @@ +线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

#####任务调度

+

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

+

#####关于多线程提升效率:

+
    +
  1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
  2. +
  3. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
  4. +
+

#####关于线程,进程的区别:

+
    +
  1. 进程,其实是操作系统对一个正在运行的程序的抽象,操作系统会给它分配独立的资源,而且每个进程之间的资源相对独立,在操作系统级别上,它是资源调度和分配的独立单位,而线程,可以看作是进程中执行的一段代码流,多个线程共享一个进程内的内存资源(除了必要的栈和程序计数器独立),线程是cpu执行的最小单位。
  2. +
  3. 进程之间不共享内存,而且在操作系统层面上相对独立,所以进程之间的通信开销是很大的,而线程共享内存,通信比较方便。
  4. +
  5. 进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块(Program Control Block,简称PCB),包含进程的描述信息和控制信息,是进程存在的唯一标志。
  6. +
  7. 线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成
  8. +
+

#####进程与线程的区别
前面讲了进程与线程,但可能你还觉得迷糊,感觉他们很类似。的确,进程与线程有着千丝万缕的关系,下面就让我们一起来理一理:

+
    +
  1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
  2. +
  3. 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
  4. +
  5. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
  6. +
  7. 调度和切换:线程上下文切换比进程上下文切换要快得多
  8. +
+
Share
\ No newline at end of file diff --git a/about/index.html b/about/index.html index 54fec6a..0675258 100644 --- a/about/index.html +++ b/about/index.html @@ -1,4 +1,4 @@ - | 唐佳写字的地方
\ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index b7e4c64..a0d6341 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方
\ No newline at end of file +Archive | 唐佳写字的地方
\ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index b7e4c64..a0d6341 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方
\ No newline at end of file +Archive | 唐佳写字的地方
\ No newline at end of file diff --git a/archives/2016/04/index.html b/archives/2016/04/index.html index 6f3d42a..e7a20e9 100644 --- a/archives/2016/04/index.html +++ b/archives/2016/04/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方
\ No newline at end of file +Archive | 唐佳写字的地方
\ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index f458627..914e27e 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方
\ No newline at end of file +Archive | 唐佳写字的地方
\ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index bd8d101..b8ac1ad 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方
\ No newline at end of file +Archive | 唐佳写字的地方
\ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 1cfc7ca..6ec1118 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方
\ No newline at end of file +Archive | 唐佳写字的地方
\ No newline at end of file diff --git a/index.html b/index.html index ecafab3..1fa75be 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

Contaniner

Mehr lesen

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Mehr lesen

哈哈

Mehr lesen

第一篇

asdasd

Mehr lesen

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Mehr lesen

\ No newline at end of file +唐佳写字的地方

线程 进程 并发 并行

#####任务调度

Read More

Contaniner

Read More

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Read More

哈哈

Read More

第一篇

asdasd

Read More

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Read More

\ No newline at end of file diff --git "a/tags/\344\271\261\345\206\231\347\232\204/index.html" "b/tags/\344\271\261\345\206\231\347\232\204/index.html" index e317478..308a2e9 100644 --- "a/tags/\344\271\261\345\206\231\347\232\204/index.html" +++ "b/tags/\344\271\261\345\206\231\347\232\204/index.html" @@ -1 +1 @@ -乱写的 | 唐佳写字的地方
\ No newline at end of file +乱写的 | 唐佳写字的地方
\ No newline at end of file From a3e875e6c876a61f8b34527d769d0a23346c8c7f Mon Sep 17 00:00:00 2001 From: tangjia Date: Thu, 28 Jul 2016 18:54:52 +0800 Subject: [PATCH 02/17] Site updated: 2016-07-28 18:54:52 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- "2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" | 4 ++-- 2016/07/20/Contaniner/index.html | 2 +- 2016/07/20/hello-world/index.html | 4 ++-- "2016/07/20/\345\223\210\345\223\210/index.html" | 2 +- .../index.html" | 5 ++--- about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/04/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- "tags/\344\271\261\345\206\231\347\232\204/index.html" | 2 +- 15 files changed, 20 insertions(+), 21 deletions(-) diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index d04eca8..8a003df 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

+Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

###1. Why should we use Servlet
For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

###2. How does it process requests
It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

@@ -10,4 +10,4 @@

Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

-
Share
第一篇
\ No newline at end of file +
Cuota
第一篇
\ No newline at end of file diff --git "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" index 032fe55..be4303e 100644 --- "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" +++ "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" @@ -1,4 +1,4 @@ -第一篇 | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/Contaniner/index.html b/2016/07/20/Contaniner/index.html index 85346aa..23364c6 100644 --- a/2016/07/20/Contaniner/index.html +++ b/2016/07/20/Contaniner/index.html @@ -1 +1 @@ -Contaniner | 唐佳写字的地方 \ No newline at end of file +Contaniner | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/hello-world/index.html b/2016/07/20/hello-world/index.html index 923632e..f8b6a66 100644 --- a/2016/07/20/hello-world/index.html +++ b/2016/07/20/hello-world/index.html @@ -1,4 +1,4 @@ -Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

+Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server
@@ -7,4 +7,4 @@

Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

-
Share
Contaniner
\ No newline at end of file +
Cuota
Contaniner
\ No newline at end of file diff --git "a/2016/07/20/\345\223\210\345\223\210/index.html" "b/2016/07/20/\345\223\210\345\223\210/index.html" index 142cde8..c4ae6b6 100644 --- "a/2016/07/20/\345\223\210\345\223\210/index.html" +++ "b/2016/07/20/\345\223\210\345\223\210/index.html" @@ -1 +1 @@ -哈哈 | 唐佳写字的地方 \ No newline at end of file +哈哈 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 2364597..67c1fde 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,5 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

#####任务调度

-

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

+线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

#####任务调度
线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

#####关于多线程提升效率:

  1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
  2. @@ -19,4 +18,4 @@
  3. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
  4. 调度和切换:线程上下文切换比进程上下文切换要快得多
-
Share
\ No newline at end of file +
Cuota
\ No newline at end of file diff --git a/about/index.html b/about/index.html index 0675258..2abf9bf 100644 --- a/about/index.html +++ b/about/index.html @@ -1,4 +1,4 @@ - | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index a0d6341..9a1d290 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index a0d6341..9a1d290 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/04/index.html b/archives/2016/04/index.html index e7a20e9..e4f3772 100644 --- a/archives/2016/04/index.html +++ b/archives/2016/04/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 914e27e..c74e1ec 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index b8ac1ad..fcf17fd 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 6ec1118..f6707f8 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index 1fa75be..1f396f3 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

线程 进程 并发 并行

#####任务调度

Read More

Contaniner

Read More

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Read More

哈哈

Read More

第一篇

asdasd

Read More

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Read More

\ No newline at end of file +唐佳写字的地方

线程 进程 并发 并行

#####任务调度
线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Leer más

Contaniner

Leer más

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Leer más

哈哈

Leer más

第一篇

asdasd

Leer más

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Leer más

\ No newline at end of file diff --git "a/tags/\344\271\261\345\206\231\347\232\204/index.html" "b/tags/\344\271\261\345\206\231\347\232\204/index.html" index 308a2e9..946708d 100644 --- "a/tags/\344\271\261\345\206\231\347\232\204/index.html" +++ "b/tags/\344\271\261\345\206\231\347\232\204/index.html" @@ -1 +1 @@ -乱写的 | 唐佳写字的地方 \ No newline at end of file +乱写的 | 唐佳写字的地方 \ No newline at end of file From a20840c13b974bf423fe6430672240f463951f38 Mon Sep 17 00:00:00 2001 From: tangjia Date: Thu, 28 Jul 2016 18:55:28 +0800 Subject: [PATCH 03/17] Site updated: 2016-07-28 18:55:28 --- .../09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- .../\347\254\254\344\270\200\347\257\207/index.html" | 4 ++-- 2016/07/20/Contaniner/index.html | 2 +- 2016/07/20/hello-world/index.html | 4 ++-- "2016/07/20/\345\223\210\345\223\210/index.html" | 2 +- .../index.html" | 12 +++++------- about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/04/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- .../\344\271\261\345\206\231\347\232\204/index.html" | 2 +- 15 files changed, 23 insertions(+), 25 deletions(-) diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 8a003df..d04eca8 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

+Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

###1. Why should we use Servlet
For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

###2. How does it process requests
It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

@@ -10,4 +10,4 @@

Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

-
Cuota
第一篇
\ No newline at end of file +
Share
第一篇
\ No newline at end of file diff --git "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" index be4303e..032fe55 100644 --- "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" +++ "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" @@ -1,4 +1,4 @@ -第一篇 | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/Contaniner/index.html b/2016/07/20/Contaniner/index.html index 23364c6..85346aa 100644 --- a/2016/07/20/Contaniner/index.html +++ b/2016/07/20/Contaniner/index.html @@ -1 +1 @@ -Contaniner | 唐佳写字的地方 \ No newline at end of file +Contaniner | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/hello-world/index.html b/2016/07/20/hello-world/index.html index f8b6a66..923632e 100644 --- a/2016/07/20/hello-world/index.html +++ b/2016/07/20/hello-world/index.html @@ -1,4 +1,4 @@ -Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

+Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server
@@ -7,4 +7,4 @@

Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

-
Cuota
Contaniner
\ No newline at end of file +
Share
Contaniner
\ No newline at end of file diff --git "a/2016/07/20/\345\223\210\345\223\210/index.html" "b/2016/07/20/\345\223\210\345\223\210/index.html" index c4ae6b6..142cde8 100644 --- "a/2016/07/20/\345\223\210\345\223\210/index.html" +++ "b/2016/07/20/\345\223\210\345\223\210/index.html" @@ -1 +1 @@ -哈哈 | 唐佳写字的地方 \ No newline at end of file +哈哈 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 67c1fde..442e805 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,21 +1,19 @@ -线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

#####任务调度
线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

-

#####关于多线程提升效率:

-
    +线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    +
    关于多线程提升效率:
    1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
    2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
    -

    #####关于线程,进程的区别:

    -
      +
      关于线程,进程的区别:
      1. 进程,其实是操作系统对一个正在运行的程序的抽象,操作系统会给它分配独立的资源,而且每个进程之间的资源相对独立,在操作系统级别上,它是资源调度和分配的独立单位,而线程,可以看作是进程中执行的一段代码流,多个线程共享一个进程内的内存资源(除了必要的栈和程序计数器独立),线程是cpu执行的最小单位。
      2. 进程之间不共享内存,而且在操作系统层面上相对独立,所以进程之间的通信开销是很大的,而线程共享内存,通信比较方便。
      3. 进程一般由程序、数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块(Program Control Block,简称PCB),包含进程的描述信息和控制信息,是进程存在的唯一标志。
      4. 线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成
      -

      #####进程与线程的区别
      前面讲了进程与线程,但可能你还觉得迷糊,感觉他们很类似。的确,进程与线程有着千丝万缕的关系,下面就让我们一起来理一理:

      +
      进程与线程的区别

      前面讲了进程与线程,但可能你还觉得迷糊,感觉他们很类似。的确,进程与线程有着千丝万缕的关系,下面就让我们一起来理一理:

      1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
      2. 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
      3. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
      4. 调度和切换:线程上下文切换比进程上下文切换要快得多
      -
    Cuota
    \ No newline at end of file +
Share
\ No newline at end of file diff --git a/about/index.html b/about/index.html index 2abf9bf..0675258 100644 --- a/about/index.html +++ b/about/index.html @@ -1,4 +1,4 @@ - | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 9a1d290..a0d6341 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 9a1d290..a0d6341 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/04/index.html b/archives/2016/04/index.html index e4f3772..e7a20e9 100644 --- a/archives/2016/04/index.html +++ b/archives/2016/04/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index c74e1ec..914e27e 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index fcf17fd..b8ac1ad 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index f6707f8..6ec1118 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index 1f396f3..1b61d10 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

线程 进程 并发 并行

#####任务调度
线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Leer más

Contaniner

Leer más

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Leer más

哈哈

Leer más

第一篇

asdasd

Leer más

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Leer más

\ No newline at end of file +唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Read More

Contaniner

Read More

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Read More

哈哈

Read More

第一篇

asdasd

Read More

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Read More

\ No newline at end of file diff --git "a/tags/\344\271\261\345\206\231\347\232\204/index.html" "b/tags/\344\271\261\345\206\231\347\232\204/index.html" index 946708d..308a2e9 100644 --- "a/tags/\344\271\261\345\206\231\347\232\204/index.html" +++ "b/tags/\344\271\261\345\206\231\347\232\204/index.html" @@ -1 +1 @@ -乱写的 | 唐佳写字的地方 \ No newline at end of file +乱写的 | 唐佳写字的地方 \ No newline at end of file From 33f1a5b4f0ec28725250bfb222c6839b27c0869d Mon Sep 17 00:00:00 2001 From: tangjia Date: Tue, 7 Feb 2017 09:49:25 +0800 Subject: [PATCH 04/17] Site updated: 2017-02-07 09:49:25 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- "2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" | 4 ++-- 2016/07/20/Contaniner/index.html | 2 +- 2016/07/20/hello-world/index.html | 4 ++-- "2016/07/20/\345\223\210\345\223\210/index.html" | 2 +- .../index.html" | 4 ++-- .../index.html" | 2 ++ about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/04/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- "tags/\344\271\261\345\206\231\347\232\204/index.html" | 2 +- 16 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 "2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index d04eca8..c87d789 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

+Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

###1. Why should we use Servlet
For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

###2. How does it process requests
It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

@@ -10,4 +10,4 @@

Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

-
Share
第一篇
\ No newline at end of file +
Cuota
第一篇
\ No newline at end of file diff --git "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" index 032fe55..14c6265 100644 --- "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" +++ "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" @@ -1,4 +1,4 @@ -第一篇 | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/Contaniner/index.html b/2016/07/20/Contaniner/index.html index 85346aa..8190455 100644 --- a/2016/07/20/Contaniner/index.html +++ b/2016/07/20/Contaniner/index.html @@ -1 +1 @@ -Contaniner | 唐佳写字的地方 \ No newline at end of file +Contaniner | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/hello-world/index.html b/2016/07/20/hello-world/index.html index 923632e..c5a6e37 100644 --- a/2016/07/20/hello-world/index.html +++ b/2016/07/20/hello-world/index.html @@ -1,4 +1,4 @@ -Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

+Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server
@@ -7,4 +7,4 @@

Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

-
Share
Contaniner
\ No newline at end of file +
Cuota
Contaniner
\ No newline at end of file diff --git "a/2016/07/20/\345\223\210\345\223\210/index.html" "b/2016/07/20/\345\223\210\345\223\210/index.html" index 142cde8..052e435 100644 --- "a/2016/07/20/\345\223\210\345\223\210/index.html" +++ "b/2016/07/20/\345\223\210\345\223\210/index.html" @@ -1 +1 @@ -哈哈 | 唐佳写字的地方 \ No newline at end of file +哈哈 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 442e805..7ea1d6e 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

+线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

关于多线程提升效率:
  1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
  2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
  3. @@ -16,4 +16,4 @@
    Share
\ No newline at end of file +
Cuota
java中的多线程
\ No newline at end of file diff --git "a/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" "b/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" new file mode 100644 index 0000000..7308eb4 --- /dev/null +++ "b/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" @@ -0,0 +1,2 @@ +java中的多线程 | 唐佳写字的地方

java中的多线程

任何程序都有一个线程,java程序已启动就已经启动了两个线程,一个是main线程,一个是gc线程,用来回收。

+
Cuota
\ No newline at end of file diff --git a/about/index.html b/about/index.html index 0675258..d7f6fd1 100644 --- a/about/index.html +++ b/about/index.html @@ -1,4 +1,4 @@ - | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index a0d6341..69e3dbe 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index a0d6341..69e3dbe 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/04/index.html b/archives/2016/04/index.html index e7a20e9..197f0ec 100644 --- a/archives/2016/04/index.html +++ b/archives/2016/04/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 914e27e..9b0f7d4 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index b8ac1ad..9a8340e 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 6ec1118..392a288 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index 1b61d10..159a71c 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Read More

Contaniner

Read More

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Read More

哈哈

Read More

第一篇

asdasd

Read More

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Read More

\ No newline at end of file +唐佳写字的地方

java中的多线程

任何程序都有一个线程,java程序已启动就已经启动了两个线程,一个是main线程,一个是gc线程,用来回收。

Leer más

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Leer más

Contaniner

Leer más

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Leer más

哈哈

Leer más

第一篇

asdasd

Leer más

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Leer más

\ No newline at end of file diff --git "a/tags/\344\271\261\345\206\231\347\232\204/index.html" "b/tags/\344\271\261\345\206\231\347\232\204/index.html" index 308a2e9..fc48bba 100644 --- "a/tags/\344\271\261\345\206\231\347\232\204/index.html" +++ "b/tags/\344\271\261\345\206\231\347\232\204/index.html" @@ -1 +1 @@ -乱写的 | 唐佳写字的地方 \ No newline at end of file +乱写的 | 唐佳写字的地方 \ No newline at end of file From 6e8436e910a80d067a1920cbdfefa39fcfb8b29c Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 09:28:06 +0800 Subject: [PATCH 05/17] Site updated: 2017-02-10 09:28:05 --- .../index.html | 4 +- .../index.html" | 7 +++ .../index.html" | 16 ++++++ .../index.html" | 4 +- .../index.html" | 23 ++++++++ .../09/\345\205\263\344\272\216GC/index.html" | 52 +++++++++++++++++++ 2016/07/20/Contaniner/index.html | 2 +- 2016/07/20/hello-world/index.html | 4 +- .../20/\345\223\210\345\223\210/index.html" | 2 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 18 +++++++ .../index.html" | 16 ++++++ about/index.html | 6 +-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 1 + archives/2016/03/index.html | 1 + archives/2016/04/index.html | 2 +- archives/2016/05/index.html | 1 + archives/2016/06/index.html | 1 + archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 1 + archives/2016/index.html | 2 +- archives/2017/02/index.html | 1 + archives/2017/index.html | 1 + archives/index.html | 2 +- index.html | 2 +- tags/JVM/index.html | 1 + .../index.html" | 2 +- .../index.html" | 1 + 31 files changed, 163 insertions(+), 24 deletions(-) create mode 100644 "2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" create mode 100644 "2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" create mode 100644 "2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" create mode 100644 "2016/06/09/\345\205\263\344\272\216GC/index.html" create mode 100644 "2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" create mode 100644 "2017/02/07/\350\260\210\350\260\210\345\255\227\347\254\246/index.html" create mode 100644 archives/2016/02/index.html create mode 100644 archives/2016/03/index.html create mode 100644 archives/2016/05/index.html create mode 100644 archives/2016/06/index.html create mode 100644 archives/2016/08/index.html create mode 100644 archives/2017/02/index.html create mode 100644 archives/2017/index.html create mode 100644 tags/JVM/index.html create mode 100644 "tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index c87d789..548bd1c 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

+Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

###1. Why should we use Servlet
For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

###2. How does it process requests
It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

@@ -10,4 +10,4 @@

Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

-
Cuota
第一篇
\ No newline at end of file +
Share
原码反码补码
\ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" new file mode 100644 index 0000000..fef3043 --- /dev/null +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -0,0 +1,7 @@ +原码反码补码 | 唐佳写字的地方

原码反码补码

Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

Q2. 为什么计算机表示带符号的数值要用补码?

1. 机器数和真值

机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
真值就是这个机器数在计算机中所代表的值
例如:
1000 0001[机器数] = -1 [真值]

+
2. 原码

原码就是符号位加 真值 的绝对值。
1 [原码] = 0000 0001
-1 [ 原码] = 1000 0001

+
3. 反码

正数的反码就是它本身,负数的反码是符号位不变,其他位取反。
1[ 反码] = 0000 0001
-1 [反码] = 1111 1110

+
4. 补码

正数的补码同样是它本身 ,负数的补码是反码+1
1[补码] = 0000 0001
-1 [补码] = 1111 1111

+

A1:

现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

+

A2:

为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
所以 3+5= 0011 + 0101 = 1111 = 8
3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

+
Share
String为什么是不可变的
\ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" new file mode 100644 index 0000000..e5b3340 --- /dev/null +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -0,0 +1,16 @@ +String为什么是不可变的 | 唐佳写字的地方

String为什么是不可变的

1. 为什么String 是不可变的?

通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

+

2. 为什么String要设计成不可变的?

    +
  1. String interning 的设计
    1
    2
    String a = "abc";
    String b = "abc";
    +
  2. +
+

如果“abc”对象实例第一次被引用指向,则在堆中一个String常量缓存池中加入”abc”,b 也指向该缓存池中的”abc”,如果String 是可变的,那么其中一个引用改变它的值将会对其他引用变量造成影响。

+
    +
  1. 安全问题
    很多连接配置就是用的String,如果中途可以被改变的话或造成安全问题。

    +
  2. +
  3. 因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因为线程安全问题而使用同步。字符串自己便是线程安全的。

    +
  4. +
  5. 类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。譬如你想加载java.sql.Connection类,而这个值被改成了myhacked.Connection,那么会对你的数据库造成不可知的破坏。
  6. +
  7. 因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。
  8. +
+

3. 怎么改变String的值?

String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

+
Share
JVM内存模型
\ No newline at end of file diff --git "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" index 14c6265..821a983 100644 --- "a/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" +++ "b/2016/04/20/\347\254\254\344\270\200\347\257\207/index.html" @@ -1,4 +1,4 @@ -第一篇 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" new file mode 100644 index 0000000..a178794 --- /dev/null +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -0,0 +1,23 @@ +JVM内存模型 | 唐佳写字的地方

JVM内存模型

JVM内存图

+

JVM在运行时内存模型:

线程私有内存区:

程序计数器(Program Counter Programming)

程序计数器可以看做是当前线程所执行的字节码的行号指示器,字节码解析器就是通过改变这个计数器的值来选取下一条要执行的代码,像分支,循环,跳转,线程恢复都需要依赖它只能知道下一条执行语句的位置。所以他是每个线程私有的。
当执行的是java方法的时候,它记录的是当前正在运行的虚拟机字节码指令的地址。当执行native方法的时候,值为Undefine,此内存区是唯一没有异常的区域。

+
虚拟机栈( VM Stack )

VM Stack
虚拟机栈描述的 Java 方法执行的内存模型,每执行一个方法就会向 stack 压入一个栈帧(Stack Frame),里面包含了局部变量表,操作数栈,动态链接,方法出口,从方法调用到执行,对应着一个栈帧的入栈到出栈,所以他也是线程私有。

+

局部变量表,也就是常说的堆和栈里面的“栈”,它包含基本数据类型,对象的引用类型( reference ),returnAddress(指向一条字节码指令的地址)

+

栈的深度决定了方法调用的深度,可以用 -Xss 修改,请求栈深度大于虚拟机允许的深度,会抛出 StackOverFlowError 异常,如果虚拟机栈是动态扩展,那么扩展的时候会申请内存,不够会抛出 OutOfMemoryError

+
本地方法栈 (Native Method Stack)

和虚拟机栈类似,只不过是针对 native 方法,有的虚拟机把两个合二为一了(Sun Hotspot)。

+

线程共享内存区

Java堆(Java Heap)

存放对象实例的地方,但并不绝对( 针对栈上分配,标量替换等优化技术)。是GC的主要区域,物理上可以使连续内存区,也可以不连续,逻辑上连续即可。通过 -Xmx -Xms 控制内存大小,内存不够时会抛出 OutOfMemoryError

+
方法区(Method Area)

存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。GC行为在此区域较少,主要是常量池回收和类型卸载。

+

直接内存(Direct Memory)

不属于JVM的运行时内存,可以用NIO中的DirectByteBuffer操作。

+

####附 JVM常用参数

+
    +
  • -XX:+PrintGCDetails 打印垃圾回收信息
  • +
  • -Xms 为Heap区域的初始值,线上环境需要与-Xmx设置为一致,否则capacity的值会来回飘动
  • +
  • -Xmx 为Heap区域的最大值
  • +
  • -Xss(或-ss) 线程栈大小(指一个线程的native空间)1.5以后是1M的默认大小
  • +
  • -XX:PermSize与-XX:MaxPermSize 方法区(永久代)的初始大小和最大值(但不是本地方法区)
  • +
  • -XX:NewRatio 老年代与新生代比率
  • +
  • -XX:SurvivorRatio Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9?因为我们的新生代有2个survivor,即S1和S22。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10。
  • +
  • -XX:MaxHeapFreeRatio GC后,如果发现空闲堆内存占到整个预估的比例小于这个值,则减小堆空间。
  • +
  • -XX:MinHeapFreeRatio GC后,如果发现空闲堆内存占到整个预估的比例大于这个值,则增大堆空间。
  • +
  • -XX:NewSize 新生代大小
  • +
+
Share
关于GC
\ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" new file mode 100644 index 0000000..8567012 --- /dev/null +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -0,0 +1,52 @@ +关于GC | 唐佳写字的地方

关于GC

先来看三个问题:

+
    +
  • 那些对象需要被回收
  • +
  • 什么时候回收
  • +
  • 怎么回收(回收的策略)
  • +
+

哪些对象需要被回收?

引用计数法

被有新的引用计数加1,引用被销毁引用减1,但是无法解决循环引用的问题。

+
1
2
3
4
5
6
Object a = new Object();
Object b = new Object();
a = b;
b = a;
a = null;
b = null;
+

执行到第五行的时候a,b引用计数均为2,然后a,b=null,引用计算减一,如果a要被清除,不需要满足引用计算为0,就是说他的一个引用b必须要被清除,但是b又引用a,要等待a被清除。所以陷入死循环。

+

可达性分析算法

把一些列 "GC ROOT"节点作为起始点开始搜索,走过的路径称为引用链(Reference Chain),当一个对象不在引用链上,那么就可以被回收了。这里有两点需要注意,什么可以作为GC ROOT,以及什么是引用.

+

GC ROOT:

+
    +
  1. static属性引用的对象
  2. +
  3. final常量引用的对象
  4. +
  5. 当前栈帧的本地变量区
  6. +
  7. native方法引用的对象
  8. +
+

引用:

+
    +
  1. 强引用,永远不会回收。
  2. +
  3. 软引用
  4. +
+
1
2
Object obj = new Obj;
SoftReference<Object> sof = new SoftReference<Object>(obj);
+

只有当内存不够的时候才回收。

+
    +
  1. 弱引用
  2. +
+
1
2
Object obj = new Obj;
WeakReference<Object> wf = new WeakReference<Object>(obj);
+

下一次垃圾回收的时候回收。

+
    +
  1. 虚引用(幽灵引用)
  2. +
+
1
2
Object obj = new Object();
PhantomRefrence<Object> pf = new PhantomRefrence<Object>(obj);
+

垃圾回收的时候就回收。

+

什么时候回收

对象优先在堆区新生代的eden分区分配,当eden分区内存不够,此时触发 Minor GC,多次存活的对象将放入老年代,老年代内存不够的话会触发Full GC,你也可以手动调用System.gc()进行回收,但这只是告诉GC线程进行垃圾回收,具体时候执行和什么时候执行还不一定(类似启动一个线程)。

+

怎么回收

怎么回收就要谈一下垃圾回收的常用算法了。

+

标记清除算法(Mark-Sweep)

标记处所有要清除的对象,然后在回收所有被标记的。
实现简单,缺点也很明显:

+
    +
  1. 效率低
  2. +
  3. 造成内存不连续,分配大对象的时候会造成GC
  4. +
+

这是最基础的垃圾回收算法。

+

复制算法(Copying)

把内存分为相等的两块,每次使用其中一块,GC时先把存活的对象复制到另一块上,在对整块清除。高效,但是浪费了一半的内存空间。但是通常不会等分,而是按8:1:1分配。

+

标记整理算法( Mark-compact)

在标记清除的基础上,对存活的对象从内存的最左端重新排序整理,使空闲的地址空间连续。缺点是效率低。

+

分代收集(Generational Collection)

这个算法没什么新的特性,主要是把堆Heap上的空间分为新生代(Young Generation) 和 老年代(Tenured Generation)。

+

所以现代商用虚拟机大部分是用这种算法清理新生代,但不是五五分,而是把它分为1 8 1,只浪费百分之十内存。

+

把新生代分为2个survivor(各占10%),一个Eden(80%),内存分配在一个survivor和Eden分区,当清理的时候,把存活的对象(一般不超过10%)复制顺序到另一个survivor分区上,然后清理当前的survivor和eden分区。下次分配内存的时候在eden和被复制的survivore分区上分配。

+

当survivor空间不够时,会向(Tenured Generation)申请内存空间。当survivor分区的对象对此未被回收(年龄计数器加一),说明这个对象可能长时间都不会被回收,那么每次在对其进行GC ROOT扫描是浪费的,所以会把它移动到老年代。

+

老年代(Tenured)的对象都是些持久不易被回收的对象,所采的回收算法一般是标记清除或标记整理。

+

新生代 GC(Minor GC):指发生在新生代的垃圾收集动作,因为 Java 对象大多都具
备朝生夕灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。

+

老年代 GC(Major GC / Full GC):指发生在老年代的 GC,出现了 Major GC,经常
会伴随至少一次的 Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里
就有直接进行 Major GC 的策略选择过程) 。MajorGC 的速度一般会比 Minor GC 慢 10
倍以上。

+
Share
线程 进程 并发 并行
\ No newline at end of file diff --git a/2016/07/20/Contaniner/index.html b/2016/07/20/Contaniner/index.html index 8190455..c8b68c1 100644 --- a/2016/07/20/Contaniner/index.html +++ b/2016/07/20/Contaniner/index.html @@ -1 +1 @@ -Contaniner | 唐佳写字的地方 \ No newline at end of file +Contaniner | 唐佳写字的地方 \ No newline at end of file diff --git a/2016/07/20/hello-world/index.html b/2016/07/20/hello-world/index.html index c5a6e37..b1798af 100644 --- a/2016/07/20/hello-world/index.html +++ b/2016/07/20/hello-world/index.html @@ -1,4 +1,4 @@ -Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

+Hello World | 唐佳写字的地方

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server
@@ -7,4 +7,4 @@

Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

-
Cuota
Contaniner
\ No newline at end of file +
Partager
Contaniner
\ No newline at end of file diff --git "a/2016/07/20/\345\223\210\345\223\210/index.html" "b/2016/07/20/\345\223\210\345\223\210/index.html" index 052e435..0248207 100644 --- "a/2016/07/20/\345\223\210\345\223\210/index.html" +++ "b/2016/07/20/\345\223\210\345\223\210/index.html" @@ -1 +1 @@ -哈哈 | 唐佳写字的地方 \ No newline at end of file +哈哈 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 7ea1d6e..99ade13 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

+线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

关于多线程提升效率:
  1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
  2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
  3. @@ -16,4 +16,4 @@
    Cuota
    java中的多线程
\ No newline at end of file +
Share
也谈谈字符
\ No newline at end of file diff --git "a/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" "b/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" index 7308eb4..2e3ea9a 100644 --- "a/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" +++ "b/2016/07/29/java\344\270\255\347\232\204\345\244\232\347\272\277\347\250\213/index.html" @@ -1,2 +1,2 @@ -java中的多线程 | 唐佳写字的地方

java中的多线程

任何程序都有一个线程,java程序已启动就已经启动了两个线程,一个是main线程,一个是gc线程,用来回收。

-
Cuota
\ No newline at end of file +Java中的多线程 | 唐佳写字的地方

Java中的多线程

任何程序都有一个线程,java程序已启动就已经启动了两个线程,一个是main线程,一个是gc线程,用来回收。

+
Partager
也谈谈字符
\ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" new file mode 100644 index 0000000..0177b2b --- /dev/null +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -0,0 +1,18 @@ +也谈谈字符 | 唐佳写字的地方

也谈谈字符

1.计算机只认识字节

计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

+
    +
  • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
  • +
+

2.怎么转换:字符编码

当计算机把字节和字符转换的时候,势必要有一种规则,这就是字符编码,比如说A,在ASCII编码中对应的数字是65,所以计算机存储的二进制是(0100_0001)。

+

3.每个国家有不同的字符集合:字符集

其实字符编码就是字符到字节的映射规则,但是如果每个国家都有自己的规则就乱了,所以就有了字符集:制定了字符的集合,规定了某个字符对应什么数字(字节)。

+

所以换个角度看,字符集是规定,字符编码是实现。

+

4. ASCII

ASCII编码规定了一些符号,字母和数字的编码,一共128个,当我们提及ASCII,既表示了一种字符集,也代表了一种字符编码。

+

5. ISO-8859-1(又称Latin-1)

ASCII 编码是美国人制定的,并没有考西欧的一些字母,考虑到一个字节有2的八次方256位,而ASCII只用了低4位,还有高四位没用,于是欧洲采用了ISO-8859-1 编码,该编码在ASCII的基础上,增加了128高四位。

+

6. GBK和GB2312

ISO-8859-1已经1byte可用的位全用完了,其他语言怎么办,于是,中国人决定2个byte来表示他们包含汉字的字符集 GB2312, GB2312zh7000多个字符,对于博大精深的汉字还是不够,于是它的超集 GBK 被制定了。

+

7. Unicode字符集 UTF编码

Unicode字符集指在统一不同国家的字符集。Unicode是一个符号集,它只规定了符号和和对应的二进制编码,他并没有规定二进制编码怎么传输和存储。比如说Unicode字符对应的数字1,你可以用1个字节,也可以用两个字节存储。而这些,是UTF(UCS Transformation Format)做的。

+

UTF: Unicode字符集的编码标准。

+
    +
  • UTF-16: 固定用两个字节表示一个字符
  • +
  • UTF-32: 固定用四个字节表示一个字符
  • +
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • +
+
Share
\ No newline at end of file diff --git "a/2017/02/07/\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2017/02/07/\350\260\210\350\260\210\345\255\227\347\254\246/index.html" new file mode 100644 index 0000000..214e202 --- /dev/null +++ "b/2017/02/07/\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -0,0 +1,16 @@ + | 唐佳写字的地方

1.计算机只认识字节

计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

+
    +
  • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

    2.怎么转换:字符编码

    当计算机把字节和字符转换的时候,势必要有一种规则,这就是字符编码,比如说A,在ASCII编码中对应的数字是65,所以计算机存储的二进制是(0100_0001)。

    3.每个国家有不同的字符集合:字符集

    其实字符编码就是字符到字节的映射规则,但是如果每个国家都有自己的规则就乱了,所以就有了字符集:制定了字符的集合,规定了某个字符对应什么数字(字节)。
  • +
+

所以换个角度看,字符集是规定,字符编码是实现。

+

4. ASCII

ASCII编码规定了一些符号,字母和数字的编码,一共128个,当我们提及ASCII,既表示了一种字符集,也代表了一种字符编码。

+

5. ISO-8859-1(又称Latin-1)

ASCII 编码是美国人制定的,并没有考西欧的一些字母,考虑到一个字节有2的八次方256位,而ASCII只用了低4位,还有高四位没用,于是欧洲采用了ISO-8859-1 编码,该编码在ASCII的基础上,增加了128高四位。

+

6. GBK和GB2312

ISO-8859-1已经1byte可用的位全用完了,其他语言怎么办,于是,中国人决定2个byte来表示他们包含汉字的字符集 GB2312, GB2312zh7000多个字符,对于博大精深的汉字还是不够,于是它的超集 GBK 被制定了。

+

7. Unicode字符集 UTF编码

Unicode字符集指在统一不同国家的字符集。Unicode是一个符号集,它只规定了符号和和对应的二进制编码,他并没有规定二进制编码怎么传输和存储。比如说Unicode字符对应的数字1,你可以用1个字节,也可以用两个字节存储。而这些,是UTF(UCS Transformation Format)做的。

+

UTF: Unicode字符集的编码标准。

+
    +
  • UTF-16: 固定用两个字节表示一个字符
  • +
  • UTF-32: 固定用四个字节表示一个字符
  • +
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • +
+
Share
\ No newline at end of file diff --git a/about/index.html b/about/index.html index d7f6fd1..6129993 100644 --- a/about/index.html +++ b/about/index.html @@ -1,4 +1,2 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 69e3dbe..855d97b 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 69e3dbe..855d97b 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html new file mode 100644 index 0000000..3b400f7 --- /dev/null +++ b/archives/2016/02/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html new file mode 100644 index 0000000..06dba26 --- /dev/null +++ b/archives/2016/03/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/04/index.html b/archives/2016/04/index.html index 197f0ec..49e0f96 100644 --- a/archives/2016/04/index.html +++ b/archives/2016/04/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html new file mode 100644 index 0000000..8ac6640 --- /dev/null +++ b/archives/2016/05/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html new file mode 100644 index 0000000..4cdfc17 --- /dev/null +++ b/archives/2016/06/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 9b0f7d4..a926b36 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html new file mode 100644 index 0000000..72184a2 --- /dev/null +++ b/archives/2016/08/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index 9a8340e..3e93a8c 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html new file mode 100644 index 0000000..bfa77d8 --- /dev/null +++ b/archives/2017/02/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html new file mode 100644 index 0000000..bfa77d8 --- /dev/null +++ b/archives/2017/index.html @@ -0,0 +1 @@ +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 392a288..19ee0f0 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index 159a71c..cdd0a5d 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

java中的多线程

任何程序都有一个线程,java程序已启动就已经启动了两个线程,一个是main线程,一个是gc线程,用来回收。

Leer más

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Leer más

Contaniner

Leer más

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Leer más

哈哈

Leer más

第一篇

asdasd

Leer más

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Leer más

\ No newline at end of file +唐佳写字的地方

也谈谈字符

1.计算机只认识字节

计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

Read More

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

Read More

关于GC

先来看三个问题:

Read More

JVM内存模型

JVM内存图

Read More

String为什么是不可变的

1. 为什么String 是不可变的?

通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

Read More

原码反码补码

Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

Q2. 为什么计算机表示带符号的数值要用补码?

1. 机器数和真值

机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
真值就是这个机器数在计算机中所代表的值
例如:
1000 0001[机器数] = -1 [真值]

Read More

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

Read More

\ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html new file mode 100644 index 0000000..3a17514 --- /dev/null +++ b/tags/JVM/index.html @@ -0,0 +1 @@ +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\344\271\261\345\206\231\347\232\204/index.html" "b/tags/\344\271\261\345\206\231\347\232\204/index.html" index fc48bba..02ef374 100644 --- "a/tags/\344\271\261\345\206\231\347\232\204/index.html" +++ "b/tags/\344\271\261\345\206\231\347\232\204/index.html" @@ -1 +1 @@ -乱写的 | 唐佳写字的地方 \ No newline at end of file +乱写的 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" new file mode 100644 index 0000000..0d02f3a --- /dev/null +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -0,0 +1 @@ +字符编码 | 唐佳写字的地方 \ No newline at end of file From 994b80d975bebf2097d08dbf18ae71b333900c59 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 10:12:00 +0800 Subject: [PATCH 06/17] Site updated: 2017-02-10 10:12:00 --- .../11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 14 ++++++++++++++ about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- tags/JVM/index.html | 2 +- .../index.html" | 2 +- 24 files changed, 45 insertions(+), 31 deletions(-) create mode 100644 "2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 548bd1c..82a95f2 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

+Http,Servlet,Servlet Contaniner | 唐佳写字的地方

Http,Servlet,Servlet Contaniner

前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

###1. Why should we use Servlet
For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

###2. How does it process requests
It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

@@ -10,4 +10,4 @@

Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

-
Share
原码反码补码
\ No newline at end of file +
Cuota
原码反码补码
\ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index fef3043..4215b6e 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -1,7 +1,7 @@ -原码反码补码 | 唐佳写字的地方

原码反码补码

Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

Q2. 为什么计算机表示带符号的数值要用补码?

1. 机器数和真值

机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
真值就是这个机器数在计算机中所代表的值
例如:
1000 0001[机器数] = -1 [真值]

+原码反码补码 | 唐佳写字的地方

原码反码补码

Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

Q2. 为什么计算机表示带符号的数值要用补码?

1. 机器数和真值

机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
真值就是这个机器数在计算机中所代表的值
例如:
1000 0001[机器数] = -1 [真值]

2. 原码

原码就是符号位加 真值 的绝对值。
1 [原码] = 0000 0001
-1 [ 原码] = 1000 0001

3. 反码

正数的反码就是它本身,负数的反码是符号位不变,其他位取反。
1[ 反码] = 0000 0001
-1 [反码] = 1111 1110

4. 补码

正数的补码同样是它本身 ,负数的补码是反码+1
1[补码] = 0000 0001
-1 [补码] = 1111 1111

A1:

现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

A2:

为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
所以 3+5= 0011 + 0101 = 1111 = 8
3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

-
Share
String为什么是不可变的
\ No newline at end of file +
Cuota
String为什么是不可变的
\ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index e5b3340..ee67dd8 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -1,4 +1,4 @@ -String为什么是不可变的 | 唐佳写字的地方

String为什么是不可变的

1. 为什么String 是不可变的?

通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

+String为什么是不可变的 | 唐佳写字的地方

String为什么是不可变的

1. 为什么String 是不可变的?

通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

2. 为什么String要设计成不可变的?

  1. String interning 的设计
    1
    2
    String a = "abc";
    String b = "abc";
  2. @@ -13,4 +13,4 @@

    3. 怎么改变String的值?

    String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

    -
Share
JVM内存模型
\ No newline at end of file +
Cuota
JVM内存模型
\ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index a178794..c760751 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -1,4 +1,4 @@ -JVM内存模型 | 唐佳写字的地方

JVM内存模型

JVM内存图

+JVM内存模型 | 唐佳写字的地方

JVM内存模型

JVM内存图

JVM在运行时内存模型:

线程私有内存区:

程序计数器(Program Counter Programming)

程序计数器可以看做是当前线程所执行的字节码的行号指示器,字节码解析器就是通过改变这个计数器的值来选取下一条要执行的代码,像分支,循环,跳转,线程恢复都需要依赖它只能知道下一条执行语句的位置。所以他是每个线程私有的。
当执行的是java方法的时候,它记录的是当前正在运行的虚拟机字节码指令的地址。当执行native方法的时候,值为Undefine,此内存区是唯一没有异常的区域。

虚拟机栈( VM Stack )

VM Stack
虚拟机栈描述的 Java 方法执行的内存模型,每执行一个方法就会向 stack 压入一个栈帧(Stack Frame),里面包含了局部变量表,操作数栈,动态链接,方法出口,从方法调用到执行,对应着一个栈帧的入栈到出栈,所以他也是线程私有。

局部变量表,也就是常说的堆和栈里面的“栈”,它包含基本数据类型,对象的引用类型( reference ),returnAddress(指向一条字节码指令的地址)

@@ -20,4 +20,4 @@

Share
关于GC

\ No newline at end of file +
Cuota
关于GC
\ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index 8567012..6b6af7e 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -1,4 +1,4 @@ -关于GC | 唐佳写字的地方
\ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 99ade13..7d7cbc9 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

+线程 进程 并发 并行 | 唐佳写字的地方

线程 进程 并发 并行

任务调度

线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

关于多线程提升效率:
  1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
  2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
  3. @@ -16,4 +16,4 @@
    Share
    也谈谈字符
\ No newline at end of file +
Cuota
也谈谈字符
\ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 0177b2b..48430f4 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -1,4 +1,4 @@ -也谈谈字符 | 唐佳写字的地方

也谈谈字符

1.计算机只认识字节

计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

+也谈谈字符 | 唐佳写字的地方

也谈谈字符

1.计算机只认识字节

计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

  • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
@@ -15,4 +15,4 @@

UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -

    Share
    \ No newline at end of file +
    Cuota
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" new file mode 100644 index 0000000..cd17523 --- /dev/null +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -0,0 +1,14 @@ +谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    +

    最近在写一个多线程爬虫,目前爬了知乎几十万数据,但是我发现我每次停止程序的时候都会造成某些数据不完整,比如说某线程一个问题的答案还没爬完就中断,要做好完美中断(当前数据完整),需要同时控制进程中断和线程中断的,我们可以用SignalHandler捕捉进程kill信号,然后在通过线程中断方法,即可解决,而这篇笔记记一下线程中断。

    +
    +

    线程中断的方式有好几种,简单讨论一下优劣。

    +

    new Thread().stop();

    最粗暴的线程中断方法,直接中断线程,但是已经不建议使用,同一些列的方法还有suspend().resume(),不推荐的原因是因为stop()终结一个线程的时候不能保证锁的释放,可能线程中断了还占用着资源,会造成死锁。

    +

    自定义stopThread() 方法

    思路是设置一个信号标识,对外暴露 stopThread() 方法,该方法的实现是将此标志设为激活状态,在线程需要被中断的时候判断此信号标识是否是激活状态,如果是激活状态,则中断线程。

    +

    局限性:

    +

    当线程阻塞或者休眠的时候,判断信号时候激活的代码都没有机会执行,所以自然中断不了线程。

    +

    stopThread()的升级版 new Thread().interrupt();

    为什么说他是stopThread()的升级版呢,因为它和stopThread()的实现思路是一样的,也是为线程设置一个中断标志,告诉线程你可以停止了,然后在安全的地方的手动判断 isInterrupt() 为true 安全中断线程。

    +

    并且该方法也可以在线程sleep()的时候中断线程,sleep()的时候如果被中断,就会抛出 InterruptedException 异常,我们可以在 catch 块中处理被中断的情况,这个时候如果想要真的中断线程,退出方法,这就是为什么线程sleep非要你手动catch InterruptedException 的原因。

    +

    先调用 interrupt 方法设置中断标志,因为sleep 抛出异常时会清除中断标志,防止下次进入循环因为没有中断标志而继续执行。

    +

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    +

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    +
    Cuota
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index 6129993..827830d 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 855d97b..dd0b9bb 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 855d97b..dd0b9bb 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index 3b400f7..da7d763 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index 06dba26..5844b0a 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index 8ac6640..3f9307b 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index 4cdfc17..44faf3b 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index a926b36..d0d6563 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index 72184a2..ca9f19f 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index 3e93a8c..c54783f 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index bfa77d8..7d85374 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index bfa77d8..7d85374 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 19ee0f0..9fc7555 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index cdd0a5d..706a411 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Read More

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Read More

    关于GC

    先来看三个问题:

    Read More

    JVM内存模型

    JVM内存图

    Read More

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Read More

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Read More

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Read More

    \ No newline at end of file +唐佳写字的地方

    谈谈线程中断

    Leer más

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Leer más

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Leer más

    关于GC

    先来看三个问题:

    Leer más

    JVM内存模型

    JVM内存图

    Leer más

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Leer más

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Leer más

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Leer más

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index 3a17514..8f594a4 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index 0d02f3a..0a4dc0d 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file From fc6cc657998ca53703bad4beb70e017a0f0a94f1 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 10:13:58 +0800 Subject: [PATCH 07/17] Site updated: 2017-02-10 10:13:57 --- .../index.html" | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index cd17523..e648361 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -2,13 +2,13 @@

    最近在写一个多线程爬虫,目前爬了知乎几十万数据,但是我发现我每次停止程序的时候都会造成某些数据不完整,比如说某线程一个问题的答案还没爬完就中断,要做好完美中断(当前数据完整),需要同时控制进程中断和线程中断的,我们可以用SignalHandler捕捉进程kill信号,然后在通过线程中断方法,即可解决,而这篇笔记记一下线程中断。

    线程中断的方式有好几种,简单讨论一下优劣。

    -

    new Thread().stop();

    最粗暴的线程中断方法,直接中断线程,但是已经不建议使用,同一些列的方法还有suspend().resume(),不推荐的原因是因为stop()终结一个线程的时候不能保证锁的释放,可能线程中断了还占用着资源,会造成死锁。

    -

    自定义stopThread() 方法

    思路是设置一个信号标识,对外暴露 stopThread() 方法,该方法的实现是将此标志设为激活状态,在线程需要被中断的时候判断此信号标识是否是激活状态,如果是激活状态,则中断线程。

    +

    new Thread().stop();

    最粗暴的线程中断方法,直接中断线程,但是已经不建议使用,同一些列的方法还有suspend().resume(),不推荐的原因是因为stop()终结一个线程的时候不能保证锁的释放,可能线程中断了还占用着资源,会造成死锁。

    +

    自定义stopThread() 方法

    思路是设置一个信号标识,对外暴露 stopThread() 方法,该方法的实现是将此标志设为激活状态,在线程需要被中断的时候判断此信号标识是否是激活状态,如果是激活状态,则中断线程。

    局限性:

    当线程阻塞或者休眠的时候,判断信号时候激活的代码都没有机会执行,所以自然中断不了线程。

    -

    stopThread()的升级版 new Thread().interrupt();

    为什么说他是stopThread()的升级版呢,因为它和stopThread()的实现思路是一样的,也是为线程设置一个中断标志,告诉线程你可以停止了,然后在安全的地方的手动判断 isInterrupt() 为true 安全中断线程。

    +

    stopThread()的升级版 new Thread().interrupt();

    为什么说他是stopThread()的升级版呢,因为它和stopThread()的实现思路是一样的,也是为线程设置一个中断标志,告诉线程你可以停止了,然后在安全的地方的手动判断 isInterrupt() 为true 安全中断线程。

    并且该方法也可以在线程sleep()的时候中断线程,sleep()的时候如果被中断,就会抛出 InterruptedException 异常,我们可以在 catch 块中处理被中断的情况,这个时候如果想要真的中断线程,退出方法,这就是为什么线程sleep非要你手动catch InterruptedException 的原因。

    先调用 interrupt 方法设置中断标志,因为sleep 抛出异常时会清除中断标志,防止下次进入循环因为没有中断标志而继续执行。

    -

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    -

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    +

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    +

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    Cuota
    \ No newline at end of file From 95606bd0c35a110043931bb62f1dddd994c7a938 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 10:20:52 +0800 Subject: [PATCH 08/17] Site updated: 2017-02-10 10:20:52 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- tags/JVM/index.html | 2 +- .../index.html" | 2 +- 24 files changed, 33 insertions(+), 33 deletions(-) diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 82a95f2..0ee78ac 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    +Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    ###1. Why should we use Servlet
    For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

    Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

    ###2. How does it process requests
    It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

    @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -
    Cuota
    原码反码补码
    \ No newline at end of file +
    Share
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index 4215b6e..4eb7f6b 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -1,7 +1,7 @@ -原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    +原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    2. 原码

    原码就是符号位加 真值 的绝对值。
    1 [原码] = 0000 0001
    -1 [ 原码] = 1000 0001

    3. 反码

    正数的反码就是它本身,负数的反码是符号位不变,其他位取反。
    1[ 反码] = 0000 0001
    -1 [反码] = 1111 1110

    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -
    Cuota
    String为什么是不可变的
    \ No newline at end of file +
    Share
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index ee67dd8..2098291 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -1,4 +1,4 @@ -String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    +String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    2. 为什么String要设计成不可变的?

    1. String interning 的设计
      1
      2
      String a = "abc";
      String b = "abc";
    2. @@ -13,4 +13,4 @@

      3. 怎么改变String的值?

      String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

      -
    Cuota
    JVM内存模型
    \ No newline at end of file +
    Share
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index c760751..2df7d22 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -1,4 +1,4 @@ -JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    +JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    JVM在运行时内存模型:

    线程私有内存区:

    程序计数器(Program Counter Programming)

    程序计数器可以看做是当前线程所执行的字节码的行号指示器,字节码解析器就是通过改变这个计数器的值来选取下一条要执行的代码,像分支,循环,跳转,线程恢复都需要依赖它只能知道下一条执行语句的位置。所以他是每个线程私有的。
    当执行的是java方法的时候,它记录的是当前正在运行的虚拟机字节码指令的地址。当执行native方法的时候,值为Undefine,此内存区是唯一没有异常的区域。

    虚拟机栈( VM Stack )

    VM Stack
    虚拟机栈描述的 Java 方法执行的内存模型,每执行一个方法就会向 stack 压入一个栈帧(Stack Frame),里面包含了局部变量表,操作数栈,动态链接,方法出口,从方法调用到执行,对应着一个栈帧的入栈到出栈,所以他也是线程私有。

    局部变量表,也就是常说的堆和栈里面的“栈”,它包含基本数据类型,对象的引用类型( reference ),returnAddress(指向一条字节码指令的地址)

    @@ -20,4 +20,4 @@

    Cuota
    关于GC

    \ No newline at end of file +
    Share
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index 6b6af7e..f25571c 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -1,4 +1,4 @@ -关于GC | 唐佳写字的地方
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 7d7cbc9..546f2d3 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    +线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    关于多线程提升效率:
    1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
    2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
    3. @@ -16,4 +16,4 @@
      Cuota
      也谈谈字符
    \ No newline at end of file +
    Share
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 48430f4..05e0e06 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -1,4 +1,4 @@ -也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    +也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
    @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -

    Cuota
    谈谈线程中断
    \ No newline at end of file +
    Share
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index e648361..406f047 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -1,4 +1,4 @@ -谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    +谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    最近在写一个多线程爬虫,目前爬了知乎几十万数据,但是我发现我每次停止程序的时候都会造成某些数据不完整,比如说某线程一个问题的答案还没爬完就中断,要做好完美中断(当前数据完整),需要同时控制进程中断和线程中断的,我们可以用SignalHandler捕捉进程kill信号,然后在通过线程中断方法,即可解决,而这篇笔记记一下线程中断。

    线程中断的方式有好几种,简单讨论一下优劣。

    @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -
    Cuota
    \ No newline at end of file +
    Share
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index 827830d..fdd0814 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index dd0b9bb..ed1048d 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index dd0b9bb..ed1048d 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index da7d763..505deb4 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index 5844b0a..675c742 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index 3f9307b..94d5479 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index 44faf3b..f983167 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index d0d6563..1bd0e14 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index ca9f19f..ae381de 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index c54783f..2cc4adb 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 7d85374..69703cb 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index 7d85374..69703cb 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 9fc7555..ee09884 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index 706a411..397890c 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    谈谈线程中断

    Leer más

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Leer más

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Leer más

    关于GC

    先来看三个问题:

    Leer más

    JVM内存模型

    JVM内存图

    Leer más

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Leer más

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Leer más

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Leer más

    \ No newline at end of file +唐佳写字的地方

    谈谈线程中断

    Read More

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Read More

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Read More

    关于GC

    先来看三个问题:

    Read More

    JVM内存模型

    JVM内存图

    Read More

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Read More

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Read More

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Read More

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index 8f594a4..6dc57fc 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index 0a4dc0d..a3d318a 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file From 6f999c278dec56b7f753bc3252f2c29d09612620 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 10:22:40 +0800 Subject: [PATCH 09/17] Site updated: 2017-02-10 10:22:40 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 3 +++ .../index.html" | 4 ++-- about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/01/index.html | 1 + archives/2017/02/index.html | 2 +- archives/2017/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- tags/JVM/index.html | 2 +- .../index.html" | 2 +- "tags/\345\271\266\345\217\221/index.html" | 1 + 27 files changed, 38 insertions(+), 33 deletions(-) create mode 100644 "2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" create mode 100644 archives/2017/01/index.html create mode 100644 "tags/\345\271\266\345\217\221/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 0ee78ac..cf2149c 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    +Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    ###1. Why should we use Servlet
    For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

    Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

    ###2. How does it process requests
    It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

    @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -
    Share
    原码反码补码
    \ No newline at end of file +
    Cuota
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index 4eb7f6b..516edf1 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -1,7 +1,7 @@ -原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    +原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    2. 原码

    原码就是符号位加 真值 的绝对值。
    1 [原码] = 0000 0001
    -1 [ 原码] = 1000 0001

    3. 反码

    正数的反码就是它本身,负数的反码是符号位不变,其他位取反。
    1[ 反码] = 0000 0001
    -1 [反码] = 1111 1110

    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -
    Share
    String为什么是不可变的
    \ No newline at end of file +
    Cuota
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index 2098291..c2b7635 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -1,4 +1,4 @@ -String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    +String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    2. 为什么String要设计成不可变的?

    1. String interning 的设计
      1
      2
      String a = "abc";
      String b = "abc";
    2. @@ -13,4 +13,4 @@

      3. 怎么改变String的值?

      String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

      -
    Share
    JVM内存模型
    \ No newline at end of file +
    Cuota
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index 2df7d22..47f70a7 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -1,4 +1,4 @@ -JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    +JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    JVM在运行时内存模型:

    线程私有内存区:

    程序计数器(Program Counter Programming)

    程序计数器可以看做是当前线程所执行的字节码的行号指示器,字节码解析器就是通过改变这个计数器的值来选取下一条要执行的代码,像分支,循环,跳转,线程恢复都需要依赖它只能知道下一条执行语句的位置。所以他是每个线程私有的。
    当执行的是java方法的时候,它记录的是当前正在运行的虚拟机字节码指令的地址。当执行native方法的时候,值为Undefine,此内存区是唯一没有异常的区域。

    虚拟机栈( VM Stack )

    VM Stack
    虚拟机栈描述的 Java 方法执行的内存模型,每执行一个方法就会向 stack 压入一个栈帧(Stack Frame),里面包含了局部变量表,操作数栈,动态链接,方法出口,从方法调用到执行,对应着一个栈帧的入栈到出栈,所以他也是线程私有。

    局部变量表,也就是常说的堆和栈里面的“栈”,它包含基本数据类型,对象的引用类型( reference ),returnAddress(指向一条字节码指令的地址)

    @@ -20,4 +20,4 @@

    Share
    关于GC

    \ No newline at end of file +
    Cuota
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index f25571c..ee861a0 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -1,4 +1,4 @@ -关于GC | 唐佳写字的地方
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 546f2d3..bf370ba 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    +线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    关于多线程提升效率:
    1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
    2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
    3. @@ -16,4 +16,4 @@
      Share
      也谈谈字符
    \ No newline at end of file +
    Cuota
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 05e0e06..9061643 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -1,4 +1,4 @@ -也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    +也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
    @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -

    Share
    谈谈线程中断
    \ No newline at end of file +
    Cuota
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file diff --git "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" new file mode 100644 index 0000000..2b900b4 --- /dev/null +++ "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" @@ -0,0 +1,3 @@ +用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到推出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    +

    实验代码:

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Cuota
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index 406f047..e47fed8 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -1,4 +1,4 @@ -谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    +谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    最近在写一个多线程爬虫,目前爬了知乎几十万数据,但是我发现我每次停止程序的时候都会造成某些数据不完整,比如说某线程一个问题的答案还没爬完就中断,要做好完美中断(当前数据完整),需要同时控制进程中断和线程中断的,我们可以用SignalHandler捕捉进程kill信号,然后在通过线程中断方法,即可解决,而这篇笔记记一下线程中断。

    线程中断的方式有好几种,简单讨论一下优劣。

    @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -
    Share
    \ No newline at end of file +
    Cuota
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index fdd0814..8bac8f0 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index ed1048d..2334f37 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index ed1048d..2334f37 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index 505deb4..38612f3 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index 675c742..740f423 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index 94d5479..c2ce16a 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index f983167..d760a65 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 1bd0e14..bc4adc0 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index ae381de..ba7104a 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index 2cc4adb..4e44468 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/01/index.html b/archives/2017/01/index.html new file mode 100644 index 0000000..f5b8aef --- /dev/null +++ b/archives/2017/01/index.html @@ -0,0 +1 @@ +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 69703cb..2fb0b6c 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index 69703cb..f6c913d 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index ee09884..49b172d 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archivo | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index 397890c..bdbc3eb 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    谈谈线程中断

    Read More

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Read More

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Read More

    关于GC

    先来看三个问题:

    Read More

    JVM内存模型

    JVM内存图

    Read More

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Read More

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Read More

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Read More

    \ No newline at end of file +唐佳写字的地方

    谈谈线程中断

    Leer más

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到推出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Leer más

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Leer más

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Leer más

    关于GC

    先来看三个问题:

    Leer más

    JVM内存模型

    JVM内存图

    Leer más

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Leer más

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Leer más

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Leer más

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index 6dc57fc..f23c514 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index a3d318a..d046ea3 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\271\266\345\217\221/index.html" "b/tags/\345\271\266\345\217\221/index.html" new file mode 100644 index 0000000..7e107b5 --- /dev/null +++ "b/tags/\345\271\266\345\217\221/index.html" @@ -0,0 +1 @@ +并发 | 唐佳写字的地方 \ No newline at end of file From 7c17764784ef2678bb1acf0ea131b9d08bbced45 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 10:23:32 +0800 Subject: [PATCH 10/17] Site updated: 2017-02-10 10:23:32 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/01/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- tags/JVM/index.html | 2 +- .../index.html" | 2 +- "tags/\345\271\266\345\217\221/index.html" | 2 +- 27 files changed, 37 insertions(+), 37 deletions(-) diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index cf2149c..23db9ee 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    +Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    ###1. Why should we use Servlet
    For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

    Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

    ###2. How does it process requests
    It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

    @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -
    Cuota
    原码反码补码
    \ No newline at end of file +
    Aktie
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index 516edf1..e69d706 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -1,7 +1,7 @@ -原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    +原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    2. 原码

    原码就是符号位加 真值 的绝对值。
    1 [原码] = 0000 0001
    -1 [ 原码] = 1000 0001

    3. 反码

    正数的反码就是它本身,负数的反码是符号位不变,其他位取反。
    1[ 反码] = 0000 0001
    -1 [反码] = 1111 1110

    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -
    Cuota
    String为什么是不可变的
    \ No newline at end of file +
    Aktie
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index c2b7635..5ee1149 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -1,4 +1,4 @@ -String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    +String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    2. 为什么String要设计成不可变的?

    1. String interning 的设计
      1
      2
      String a = "abc";
      String b = "abc";
    2. @@ -13,4 +13,4 @@

      3. 怎么改变String的值?

      String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

      -
    Cuota
    JVM内存模型
    \ No newline at end of file +
    Aktie
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index 47f70a7..181d498 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -1,4 +1,4 @@ -JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    +JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    JVM在运行时内存模型:

    线程私有内存区:

    程序计数器(Program Counter Programming)

    程序计数器可以看做是当前线程所执行的字节码的行号指示器,字节码解析器就是通过改变这个计数器的值来选取下一条要执行的代码,像分支,循环,跳转,线程恢复都需要依赖它只能知道下一条执行语句的位置。所以他是每个线程私有的。
    当执行的是java方法的时候,它记录的是当前正在运行的虚拟机字节码指令的地址。当执行native方法的时候,值为Undefine,此内存区是唯一没有异常的区域。

    虚拟机栈( VM Stack )

    VM Stack
    虚拟机栈描述的 Java 方法执行的内存模型,每执行一个方法就会向 stack 压入一个栈帧(Stack Frame),里面包含了局部变量表,操作数栈,动态链接,方法出口,从方法调用到执行,对应着一个栈帧的入栈到出栈,所以他也是线程私有。

    局部变量表,也就是常说的堆和栈里面的“栈”,它包含基本数据类型,对象的引用类型( reference ),returnAddress(指向一条字节码指令的地址)

    @@ -20,4 +20,4 @@

    Cuota
    关于GC

    \ No newline at end of file +
    Aktie
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index ee861a0..925b507 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -1,4 +1,4 @@ -关于GC | 唐佳写字的地方
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index bf370ba..000f8db 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    +线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    关于多线程提升效率:
    1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
    2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
    3. @@ -16,4 +16,4 @@
      Cuota
      也谈谈字符
    \ No newline at end of file +
    Aktie
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 9061643..510e423 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -1,4 +1,4 @@ -也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    +也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
    @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -

    Cuota
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file +
    Aktie
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file diff --git "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" index 2b900b4..c6a267b 100644 --- "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" +++ "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" @@ -1,3 +1,3 @@ -用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到推出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    +用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    实验代码:

    -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Cuota
    谈谈线程中断
    \ No newline at end of file +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Aktie
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index e47fed8..62c6b2e 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -1,4 +1,4 @@ -谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    +谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    最近在写一个多线程爬虫,目前爬了知乎几十万数据,但是我发现我每次停止程序的时候都会造成某些数据不完整,比如说某线程一个问题的答案还没爬完就中断,要做好完美中断(当前数据完整),需要同时控制进程中断和线程中断的,我们可以用SignalHandler捕捉进程kill信号,然后在通过线程中断方法,即可解决,而这篇笔记记一下线程中断。

    线程中断的方式有好几种,简单讨论一下优劣。

    @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -
    Cuota
    \ No newline at end of file +
    Aktie
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index 8bac8f0..deb4a3f 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 2334f37..2669c1c 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 2334f37..2669c1c 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index 38612f3..5f8b138 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index 740f423..28fd463 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index c2ce16a..bf1e60e 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index d760a65..cf3b8b8 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index bc4adc0..7e334b5 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index ba7104a..9ac96a4 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index 4e44468..f67b9e9 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/01/index.html b/archives/2017/01/index.html index f5b8aef..3ba25d2 100644 --- a/archives/2017/01/index.html +++ b/archives/2017/01/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 2fb0b6c..25274a7 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index f6c913d..5677cba 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 49b172d..b5f74fd 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archivo | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index bdbc3eb..ec043a4 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    谈谈线程中断

    Leer más

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到推出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Leer más

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Leer más

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Leer más

    关于GC

    先来看三个问题:

    Leer más

    JVM内存模型

    JVM内存图

    Leer más

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Leer más

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Leer más

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Leer más

    \ No newline at end of file +唐佳写字的地方

    谈谈线程中断

    Mehr lesen

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Mehr lesen

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Mehr lesen

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Mehr lesen

    关于GC

    先来看三个问题:

    Mehr lesen

    JVM内存模型

    JVM内存图

    Mehr lesen

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Mehr lesen

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Mehr lesen

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Mehr lesen

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index f23c514..adddded 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index d046ea3..2fe4009 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\271\266\345\217\221/index.html" "b/tags/\345\271\266\345\217\221/index.html" index 7e107b5..b8fc15b 100644 --- "a/tags/\345\271\266\345\217\221/index.html" +++ "b/tags/\345\271\266\345\217\221/index.html" @@ -1 +1 @@ -并发 | 唐佳写字的地方 \ No newline at end of file +并发 | 唐佳写字的地方 \ No newline at end of file From 0d4de039a0fe423c6a55c527986037664a01fab5 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 10:25:00 +0800 Subject: [PATCH 11/17] Site updated: 2017-02-10 10:24:59 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- about/index.html | 2 +- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/01/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/index.html | 2 +- archives/index.html | 2 +- index.html | 2 +- tags/JVM/index.html | 2 +- "tags/Java\345\237\272\347\241\200/index.html" | 1 + .../index.html" | 2 +- "tags/\345\271\266\345\217\221/index.html" | 2 +- .../index.html" | 1 + 29 files changed, 29 insertions(+), 27 deletions(-) create mode 100644 "tags/Java\345\237\272\347\241\200/index.html" create mode 100644 "tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 23db9ee..3de2717 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -
    Aktie
    原码反码补码
    \ No newline at end of file +
    Aktie
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index e69d706..f2276e0 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -4,4 +4,4 @@
    3
    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -Aktie
    String为什么是不可变的
    \ No newline at end of file +Aktie
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index 5ee1149..4e5e043 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -13,4 +13,4 @@

    3. 怎么改变String的值?

    String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

    -Aktie
    JVM内存模型
    \ No newline at end of file +Aktie
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index 181d498..d4460b4 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -20,4 +20,4 @@

    Aktie
    关于GC
    \ No newline at end of file +Aktie
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index 925b507..c337ce9 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -49,4 +49,4 @@

    Aktie
    线程 进程 并发 并行
    \ No newline at end of file +Aktie
    线程 进程 并发 并行
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 000f8db..f2ad89a 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -16,4 +16,4 @@

    Aktie
    也谈谈字符
    \ No newline at end of file +Aktie
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 510e423..659a493 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -
    Aktie
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file +Aktie
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file diff --git "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" index c6a267b..52467ba 100644 --- "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" +++ "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" @@ -1,3 +1,3 @@ 用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    实验代码:

    -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Aktie
    谈谈线程中断
    \ No newline at end of file +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Aktie
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index 62c6b2e..484616d 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -Aktie
    \ No newline at end of file +Aktie
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index deb4a3f..2c33586 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ | 唐佳写字的地方 \ No newline at end of file + \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 2669c1c..806d71e 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 2669c1c..806d71e 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index 5f8b138..995df77 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index 28fd463..e4105cc 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index bf1e60e..ecc7a40 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index cf3b8b8..bab7c1e 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 7e334b5..2bc138d 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index 9ac96a4..d5808bf 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index f67b9e9..b61ab12 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/01/index.html b/archives/2017/01/index.html index 3ba25d2..cc5b6e1 100644 --- a/archives/2017/01/index.html +++ b/archives/2017/01/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 25274a7..7ce7ab7 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index 5677cba..851b25d 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index b5f74fd..5ddb1c7 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index ec043a4..a3c9735 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    谈谈线程中断

    Mehr lesen

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Mehr lesen

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Mehr lesen

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Mehr lesen

    关于GC

    先来看三个问题:

    Mehr lesen

    JVM内存模型

    JVM内存图

    Mehr lesen

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Mehr lesen

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Mehr lesen

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Mehr lesen

    \ No newline at end of file +唐佳写字的地方

    谈谈线程中断

    Mehr lesen

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Mehr lesen

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Mehr lesen

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Mehr lesen

    关于GC

    先来看三个问题:

    Mehr lesen

    JVM内存模型

    JVM内存图

    Mehr lesen

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Mehr lesen

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Mehr lesen

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Mehr lesen

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index adddded..a2abca7 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/Java\345\237\272\347\241\200/index.html" "b/tags/Java\345\237\272\347\241\200/index.html" new file mode 100644 index 0000000..0296b84 --- /dev/null +++ "b/tags/Java\345\237\272\347\241\200/index.html" @@ -0,0 +1 @@ +Java基础 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index 2fe4009..7415c7e 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\271\266\345\217\221/index.html" "b/tags/\345\271\266\345\217\221/index.html" index b8fc15b..36bf221 100644 --- "a/tags/\345\271\266\345\217\221/index.html" +++ "b/tags/\345\271\266\345\217\221/index.html" @@ -1 +1 @@ -并发 | 唐佳写字的地方 \ No newline at end of file +并发 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" new file mode 100644 index 0000000..afd7ecb --- /dev/null +++ "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" @@ -0,0 +1 @@ +计算机基础 | 唐佳写字的地方 \ No newline at end of file From 44269661a9487da0f1e04c29a5a6b3a840c539cd Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 13:00:13 +0800 Subject: [PATCH 12/17] Site updated: 2017-02-10 13:00:13 --- .../index.html | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../09/\345\205\263\344\272\216GC/index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 ++ .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 1 + .../index.html" | 25 +++++++++++++++++++ about/index.html | 2 +- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/01/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/08/index.html | 1 + archives/2017/index.html | 2 +- archives/index.html | 2 +- archives/page/2/index.html | 1 + index.html | 2 +- page/2/index.html | 1 + tags/JVM/index.html | 2 +- .../Java\345\237\272\347\241\200/index.html" | 2 +- .../index.html" | 2 +- "tags/\345\271\266\345\217\221/index.html" | 2 +- .../index.html" | 1 + .../index.html" | 2 +- 36 files changed, 61 insertions(+), 29 deletions(-) create mode 100644 "2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" create mode 100644 "2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" create mode 100644 "2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" create mode 100644 archives/2017/08/index.html create mode 100644 archives/page/2/index.html create mode 100644 page/2/index.html create mode 100644 "tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 3de2717..788a080 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -Aktie
    原码反码补码
    \ No newline at end of file +Aktie
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index f2276e0..cd79393 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -4,4 +4,4 @@
    3
    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -Aktie
    String为什么是不可变的
    \ No newline at end of file +Aktie
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index 4e5e043..533f863 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -13,4 +13,4 @@

    3. 怎么改变String的值?

    String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

    -Aktie
    JVM内存模型
    \ No newline at end of file +Aktie
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index d4460b4..c3e640e 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -20,4 +20,4 @@

    Aktie
    关于GC
    \ No newline at end of file +Aktie
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index c337ce9..5889be5 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -49,4 +49,4 @@

    Aktie
    线程 进程 并发 并行
    \ No newline at end of file +Aktie
    线程 进程 并发 并行
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index f2ad89a..0d815da 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -16,4 +16,4 @@

    Aktie
    也谈谈字符
    \ No newline at end of file +Aktie
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 659a493..54bc551 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -
    Aktie
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file +Aktie
    好无聊啊~写写排序算法?
    \ No newline at end of file diff --git "a/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" "b/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" new file mode 100644 index 0000000..8b27612 --- /dev/null +++ "b/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" @@ -0,0 +1,2 @@ +好无聊啊~写写排序算法? | 唐佳写字的地方

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }
    +
    Aktie
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file diff --git "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" index 52467ba..1fc78ff 100644 --- "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" +++ "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" @@ -1,3 +1,3 @@ 用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    实验代码:

    -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Aktie
    谈谈线程中断
    \ No newline at end of file +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Aktie
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index 484616d..c5185fc 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -Aktie
    \ No newline at end of file +Aktie
    笔记:关于协议和IO的基础
    \ No newline at end of file diff --git "a/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" "b/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" new file mode 100644 index 0000000..ed3487d --- /dev/null +++ "b/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" @@ -0,0 +1 @@ +笔记:关于协议和IO的基础 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" "b/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" new file mode 100644 index 0000000..6adbe17 --- /dev/null +++ "b/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" @@ -0,0 +1,25 @@ +笔记:关于TCP协议和IO的基础 | 唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    +

    1. TCP协议为什么比UDP可靠

      +
    • 首先,TCP协议在传输数据前需要跟服务器进行握手,确保了服务器可以正常访问和回复。
    • +
    • 其次,TCP每次传输数据都要求对端确认,如果没有确认会重传。
    • +
    • TCP会对传输的数据分块并排序,每一块都要一个序列号,对端收到的时候会把块按序号重新排列,重复的删去,这保证了数据的完整性和有序性。
    • +
    • TCP是面向连接的,面向连接指的是在传输数据前,双端应该先通过三次握手建立连接。
    • +
    +

    2. TCP连接三次握手

    TCP连接三次握手

    +
      +
    • 客户端发送SYN分节,告诉服务端初始序列号:j,通常不包含其他数据,所在IP数据报中只有IP首部和TCP首部。
    • +
    • 服务器针对j,回应 ACK:j+1,同时向客户端发送SYN k,以确保客户端也能正常回应。
    • +
    • 客户端回应ACK k+1。
    • +
    +

    3. 为什么TCP三次握手而不是两次

    我能想到一个场景,客户端向服务器发送第一次SYN后,假如说网络延时,SYN一直没到服务器,客户端就closed了,后面服务器接到SYN回应ACK,两次握手已经完了,这个时候客户端的状态对服务器是不可知的,服务器没法判断建立成功了没。

    +

    4. TCP关闭四次挥手

    TCP四次挥手

    +
      +
    • A端发送FIN n,表示我已经没有数据可以传给你了,请求关闭这个连接。
    • +
    • B端收到FIN n,回复ACK n+1,表示我已经收到这个请求,然后给应用层传递一个文件结束符,放入B端待读数据队列的末尾,告诉应用层A端已经没有数据可以传输了
    • +
    • B端应用读到文件结束符后调用close套接字,并向A发送FIN m。
    • +
    • A端回复ACK m+1。
    • +
    +

    5. 为什么关闭要四次握手

    关闭不一定是四次握手,因为连接和关闭的机制原理其实是一样的,都是双端一应一答,只不过连接的时候把B端的应答放在一起了,而关闭理论上不放在一起是因为当A端告诉B端要关闭连接的时候,B端可能还有一些东西还要处理,比如说还有可能要发送一些数据给A端,所以只能先回复A的FIN,告诉它我收到连接了,等处理完了再发送FIN给A端。

    +

    6. 端口到底是什么

    我指的是网络传输中虚拟的端口,显然只有在需要传输交互的时候才有端口的概念,所以端口可以看做是计算机给进程维护的一个与外部通信的标识号,比如说A程序要给另一台服务器的B进程发信息,找到服务器后,必须要通过一个标识才能知道要发给哪个进程。数据而端口正式这个标识。系统在为每个端口维护了一个队列,新来的数据只要放到对应队列里就可以了。

    +

    为什么计算的端口通常最大是65535,因为在传输层的协议中Header Format最前端是Source Port和Destination Port,每个都是2个字节。所以说这是协议规定的,并不是什么物力资源限制。

    +
    Aktie
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index 2c33586..48a3a4b 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ | 唐佳写字的地方 \ No newline at end of file + \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 806d71e..110461c 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 806d71e..110461c 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index 995df77..d3fc945 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index e4105cc..cfb197d 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index ecc7a40..36d7b75 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index bab7c1e..aa90c0c 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 2bc138d..27931d0 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index d5808bf..18b2b81 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index b61ab12..5e67f3e 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/01/index.html b/archives/2017/01/index.html index cc5b6e1..cdb47c5 100644 --- a/archives/2017/01/index.html +++ b/archives/2017/01/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 7ce7ab7..14dbf70 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/08/index.html b/archives/2017/08/index.html new file mode 100644 index 0000000..d712690 --- /dev/null +++ b/archives/2017/08/index.html @@ -0,0 +1 @@ +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index 851b25d..dc659b1 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 5ddb1c7..558c902 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/page/2/index.html b/archives/page/2/index.html new file mode 100644 index 0000000..be9afc4 --- /dev/null +++ b/archives/page/2/index.html @@ -0,0 +1 @@ +Archiv | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index a3c9735..b53267b 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    谈谈线程中断

    Mehr lesen

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Mehr lesen

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Mehr lesen

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Mehr lesen

    关于GC

    先来看三个问题:

    Mehr lesen

    JVM内存模型

    JVM内存图

    Mehr lesen

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Mehr lesen

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Mehr lesen

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Mehr lesen

    \ No newline at end of file +唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    Mehr lesen

    笔记:关于协议和IO的基础

    Mehr lesen

    谈谈线程中断

    Mehr lesen

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Mehr lesen

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }

    Mehr lesen

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Mehr lesen

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Mehr lesen

    关于GC

    先来看三个问题:

    Mehr lesen

    JVM内存模型

    JVM内存图

    Mehr lesen

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Mehr lesen

    \ No newline at end of file diff --git a/page/2/index.html b/page/2/index.html new file mode 100644 index 0000000..acade21 --- /dev/null +++ b/page/2/index.html @@ -0,0 +1 @@ +唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Mehr lesen

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Mehr lesen

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index a2abca7..7fc769d 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/Java\345\237\272\347\241\200/index.html" "b/tags/Java\345\237\272\347\241\200/index.html" index 0296b84..ffe0230 100644 --- "a/tags/Java\345\237\272\347\241\200/index.html" +++ "b/tags/Java\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -Java基础 | 唐佳写字的地方 \ No newline at end of file +Java基础 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index 7415c7e..269b06a 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\271\266\345\217\221/index.html" "b/tags/\345\271\266\345\217\221/index.html" index 36bf221..319d843 100644 --- "a/tags/\345\271\266\345\217\221/index.html" +++ "b/tags/\345\271\266\345\217\221/index.html" @@ -1 +1 @@ -并发 | 唐佳写字的地方 \ No newline at end of file +并发 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" "b/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" new file mode 100644 index 0000000..7e82232 --- /dev/null +++ "b/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" @@ -0,0 +1 @@ +排序 算法 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" index afd7ecb..59832d2 100644 --- "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" +++ "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -计算机基础 | 唐佳写字的地方 \ No newline at end of file +计算机基础 | 唐佳写字的地方 \ No newline at end of file From 29d7d9b340ce5ce0e6ca3ce8524168326dc6ba05 Mon Sep 17 00:00:00 2001 From: tangjia Date: Fri, 10 Feb 2017 13:47:02 +0800 Subject: [PATCH 13/17] Site updated: 2017-02-10 13:47:01 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 4 ++-- .../index.html" | 2 +- .../index.html" | 4 ++-- about/index.html | 4 ++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/01/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/08/index.html | 2 +- archives/2017/index.html | 2 +- archives/index.html | 2 +- archives/page/2/index.html | 2 +- index.html | 2 +- page/2/index.html | 2 +- tags/JVM/index.html | 2 +- "tags/Java\345\237\272\347\241\200/index.html" | 2 +- .../index.html" | 2 +- "tags/\345\271\266\345\217\221/index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- 36 files changed, 48 insertions(+), 48 deletions(-) diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 788a080..054f572 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -1,4 +1,4 @@ -Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    +Http,Servlet,Servlet Contaniner | 唐佳写字的地方

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    ###1. Why should we use Servlet
    For a B/S application,the most important thing is to response the different requests correctly ,but the requests from different clients are confused and disorderly so that the server is hard to analyse and response.So there is a protocol called HTTP(HyperText Transfer Protocol)to standard the request and response.

    Back to Java Web, how does it recieve the requests from clients? So it comes the Servlet,Java itself doesn’t provide realization fot Servlet,it only define a standard for Servlet,or Interface,but you hava not to implement the interfaces,because there are some server software ,which have implemented the interfaces for you,like Tomcat,Jetty.

    ###2. How does it process requests
    It’s strange and a little stupid to talk about how does a standard work,yes,it just define how to work.

    @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -
    Aktie
    原码反码补码
    \ No newline at end of file +
    Share
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index cd79393..b9c6cf3 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -1,7 +1,7 @@ -原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    +原码反码补码 | 唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    2. 原码

    原码就是符号位加 真值 的绝对值。
    1 [原码] = 0000 0001
    -1 [ 原码] = 1000 0001

    3. 反码

    正数的反码就是它本身,负数的反码是符号位不变,其他位取反。
    1[ 反码] = 0000 0001
    -1 [反码] = 1111 1110

    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -
    Aktie
    String为什么是不可变的
    \ No newline at end of file +
    Share
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index 533f863..25b5ecb 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -1,4 +1,4 @@ -String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    +String为什么是不可变的 | 唐佳写字的地方

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    2. 为什么String要设计成不可变的?

    1. String interning 的设计
      1
      2
      String a = "abc";
      String b = "abc";
    2. @@ -13,4 +13,4 @@

      3. 怎么改变String的值?

      String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

      -
    Aktie
    JVM内存模型
    \ No newline at end of file +
    Share
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index c3e640e..78346cb 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -1,4 +1,4 @@ -JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    +JVM内存模型 | 唐佳写字的地方

    JVM内存模型

    JVM内存图

    JVM在运行时内存模型:

    线程私有内存区:

    程序计数器(Program Counter Programming)

    程序计数器可以看做是当前线程所执行的字节码的行号指示器,字节码解析器就是通过改变这个计数器的值来选取下一条要执行的代码,像分支,循环,跳转,线程恢复都需要依赖它只能知道下一条执行语句的位置。所以他是每个线程私有的。
    当执行的是java方法的时候,它记录的是当前正在运行的虚拟机字节码指令的地址。当执行native方法的时候,值为Undefine,此内存区是唯一没有异常的区域。

    虚拟机栈( VM Stack )

    VM Stack
    虚拟机栈描述的 Java 方法执行的内存模型,每执行一个方法就会向 stack 压入一个栈帧(Stack Frame),里面包含了局部变量表,操作数栈,动态链接,方法出口,从方法调用到执行,对应着一个栈帧的入栈到出栈,所以他也是线程私有。

    局部变量表,也就是常说的堆和栈里面的“栈”,它包含基本数据类型,对象的引用类型( reference ),returnAddress(指向一条字节码指令的地址)

    @@ -20,4 +20,4 @@

    Aktie
    关于GC

    \ No newline at end of file +
    Share
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index 5889be5..3d83380 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -1,4 +1,4 @@ -关于GC | 唐佳写字的地方
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index 0d815da..d082e38 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -1,4 +1,4 @@ -线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    +线程 进程 并发 并行 | 唐佳写字的地方

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    关于多线程提升效率:
    1. 在单核cpu下,程序存在大量等待的耗时操作,比如从网络接受数据,从硬盘读取大文件,也就是所谓的阻塞,此时cpu处于闲置状态,此时多线程能提升效率,宏观上程序是并行的,但是微观上仍旧不是并行的。
    2. 在多核cpu下,程序能够做到真正的并行,此时能提高效率。
    3. @@ -16,4 +16,4 @@
      Aktie
      也谈谈字符
    \ No newline at end of file +
    Share
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 54bc551..562e88a 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -1,4 +1,4 @@ -也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    +也谈谈字符 | 唐佳写字的地方

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    • 字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
    @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -

    Aktie
    好无聊啊~写写排序算法?
    \ No newline at end of file +
    Share
    好无聊啊~写写排序算法?
    \ No newline at end of file diff --git "a/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" "b/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" index 8b27612..3d200c0 100644 --- "a/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" +++ "b/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" @@ -1,2 +1,2 @@ -好无聊啊~写写排序算法? | 唐佳写字的地方

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }
    -
    Aktie
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file +好无聊啊~写写排序算法? | 唐佳写字的地方

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }
    +
    Share
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file diff --git "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" index 1fc78ff..da36037 100644 --- "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" +++ "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" @@ -1,3 +1,3 @@ -用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    +用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    实验代码:

    -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Aktie
    谈谈线程中断
    \ No newline at end of file +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Share
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index c5185fc..d32c144 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -1,4 +1,4 @@ -谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    +谈谈线程中断 | 唐佳写字的地方

    谈谈线程中断

    最近在写一个多线程爬虫,目前爬了知乎几十万数据,但是我发现我每次停止程序的时候都会造成某些数据不完整,比如说某线程一个问题的答案还没爬完就中断,要做好完美中断(当前数据完整),需要同时控制进程中断和线程中断的,我们可以用SignalHandler捕捉进程kill信号,然后在通过线程中断方法,即可解决,而这篇笔记记一下线程中断。

    线程中断的方式有好几种,简单讨论一下优劣。

    @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -
    Aktie
    笔记:关于协议和IO的基础
    \ No newline at end of file +
    Share
    笔记:关于协议和IO的基础
    \ No newline at end of file diff --git "a/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" "b/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" index ed3487d..4b8b3d0 100644 --- "a/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" +++ "b/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -笔记:关于协议和IO的基础 | 唐佳写字的地方 \ No newline at end of file +笔记:关于协议和IO的基础 | 唐佳写字的地方 \ No newline at end of file diff --git "a/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" "b/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" index 6adbe17..b4c9d0e 100644 --- "a/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" +++ "b/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" @@ -1,4 +1,4 @@ -笔记:关于TCP协议和IO的基础 | 唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    +笔记:关于TCP协议和IO的基础 | 唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    1. TCP协议为什么比UDP可靠

    • 首先,TCP协议在传输数据前需要跟服务器进行握手,确保了服务器可以正常访问和回复。
    • 其次,TCP每次传输数据都要求对端确认,如果没有确认会重传。
    • @@ -22,4 +22,4 @@

      5. 为什么关闭要四次握手

      关闭不一定是四次握手,因为连接和关闭的机制原理其实是一样的,都是双端一应一答,只不过连接的时候把B端的应答放在一起了,而关闭理论上不放在一起是因为当A端告诉B端要关闭连接的时候,B端可能还有一些东西还要处理,比如说还有可能要发送一些数据给A端,所以只能先回复A的FIN,告诉它我收到连接了,等处理完了再发送FIN给A端。

      6. 端口到底是什么

      我指的是网络传输中虚拟的端口,显然只有在需要传输交互的时候才有端口的概念,所以端口可以看做是计算机给进程维护的一个与外部通信的标识号,比如说A程序要给另一台服务器的B进程发信息,找到服务器后,必须要通过一个标识才能知道要发给哪个进程。数据而端口正式这个标识。系统在为每个端口维护了一个队列,新来的数据只要放到对应队列里就可以了。

      为什么计算的端口通常最大是65535,因为在传输层的协议中Header Format最前端是Source Port和Destination Port,每个都是2个字节。所以说这是协议规定的,并不是什么物力资源限制。

      -
    Aktie
    \ No newline at end of file +
    Share
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index 48a3a4b..9845bfb 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,2 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index 110461c..fc48819 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index 110461c..fc48819 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index d3fc945..ad1eaac 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index cfb197d..60ce3da 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index 36d7b75..5ff4698 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index aa90c0c..12edb4b 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index 27931d0..e658015 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index 18b2b81..3913a21 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index 5e67f3e..152aafc 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/01/index.html b/archives/2017/01/index.html index cdb47c5..3fac7d7 100644 --- a/archives/2017/01/index.html +++ b/archives/2017/01/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 14dbf70..10e520c 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/08/index.html b/archives/2017/08/index.html index d712690..4ff019d 100644 --- a/archives/2017/08/index.html +++ b/archives/2017/08/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index dc659b1..0f809e5 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 558c902..3e66ae9 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/page/2/index.html b/archives/page/2/index.html index be9afc4..a34fc8c 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -1 +1 @@ -Archiv | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index b53267b..ddc729a 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    Mehr lesen

    笔记:关于协议和IO的基础

    Mehr lesen

    谈谈线程中断

    Mehr lesen

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Mehr lesen

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }

    Mehr lesen

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Mehr lesen

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Mehr lesen

    关于GC

    先来看三个问题:

    Mehr lesen

    JVM内存模型

    JVM内存图

    Mehr lesen

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Mehr lesen

    \ No newline at end of file +唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    Read More

    笔记:关于协议和IO的基础

    Read More

    谈谈线程中断

    Read More

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Read More

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }

    Read More

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Read More

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Read More

    关于GC

    先来看三个问题:

    Read More

    JVM内存模型

    JVM内存图

    Read More

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Read More

    \ No newline at end of file diff --git a/page/2/index.html b/page/2/index.html index acade21..7496bcd 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -1 +1 @@ -唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Mehr lesen

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Mehr lesen

    \ No newline at end of file +唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Read More

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Read More

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index 7fc769d..30bedbf 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/Java\345\237\272\347\241\200/index.html" "b/tags/Java\345\237\272\347\241\200/index.html" index ffe0230..1c8f5d0 100644 --- "a/tags/Java\345\237\272\347\241\200/index.html" +++ "b/tags/Java\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -Java基础 | 唐佳写字的地方 \ No newline at end of file +Java基础 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index 269b06a..8f460a9 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\271\266\345\217\221/index.html" "b/tags/\345\271\266\345\217\221/index.html" index 319d843..47a0e39 100644 --- "a/tags/\345\271\266\345\217\221/index.html" +++ "b/tags/\345\271\266\345\217\221/index.html" @@ -1 +1 @@ -并发 | 唐佳写字的地方 \ No newline at end of file +并发 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" "b/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" index 7e82232..3df0a23 100644 --- "a/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" +++ "b/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" @@ -1 +1 @@ -排序 算法 | 唐佳写字的地方 \ No newline at end of file +排序 算法 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" index 59832d2..ee561fe 100644 --- "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" +++ "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -计算机基础 | 唐佳写字的地方 \ No newline at end of file +计算机基础 | 唐佳写字的地方 \ No newline at end of file From 04c3060b4de82be2b249f5c6f745cf1fe2836493 Mon Sep 17 00:00:00 2001 From: tangjia Date: Mon, 13 Feb 2017 11:59:04 +0800 Subject: [PATCH 14/17] Site updated: 2017-02-13 11:59:03 --- 2015/09/11/Http-Servlet-Servlet-Contaniner/index.html | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- "2016/06/09/\345\205\263\344\272\216GC/index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 4 ++-- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- about/index.html | 5 +++-- archives/2015/09/index.html | 2 +- archives/2015/index.html | 2 +- archives/2016/02/index.html | 2 +- archives/2016/03/index.html | 2 +- archives/2016/05/index.html | 2 +- archives/2016/06/index.html | 2 +- archives/2016/07/index.html | 2 +- archives/2016/08/index.html | 2 +- archives/2016/index.html | 2 +- archives/2017/01/index.html | 2 +- archives/2017/02/index.html | 2 +- archives/2017/08/index.html | 1 - archives/2017/index.html | 2 +- archives/index.html | 2 +- archives/page/2/index.html | 2 +- index.html | 2 +- page/2/index.html | 2 +- tags/JVM/index.html | 2 +- "tags/Java\345\237\272\347\241\200/index.html" | 2 +- .../index.html" | 2 +- "tags/\345\271\266\345\217\221/index.html" | 2 +- .../index.html" | 2 +- .../index.html" | 2 +- 36 files changed, 38 insertions(+), 38 deletions(-) rename "2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" => "2016/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" (59%) delete mode 100644 archives/2017/08/index.html diff --git a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html index 054f572..96bda1f 100644 --- a/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html +++ b/2015/09/11/Http-Servlet-Servlet-Contaniner/index.html @@ -10,4 +10,4 @@

    Second,wo should write a General Servlet to recieve all the messages to the binding port,it must have two basic fuctions:anaylsing the whole message and fetch what you need,delivering the message that you fetch to the corresponding procedure.

    Third,when the procedure recieve the right request,we start to process it and build the response,then we deliver it to the General Servlet.

    Forth,the General Servlet recieves the reponse and decorates it to satisfy the HTTP,then deliver it to the fit place.

    -
    Share
    原码反码补码
    \ No newline at end of file +Share
    原码反码补码
    \ No newline at end of file diff --git "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" index b9c6cf3..1744822 100644 --- "a/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" +++ "b/2016/02/07/\345\216\237\347\240\201\345\217\215\347\240\201\350\241\245\347\240\201/index.html" @@ -4,4 +4,4 @@
    3
    4. 补码

    正数的补码同样是它本身 ,负数的补码是反码+1
    1[补码] = 0000 0001
    -1 [补码] = 1111 1111

    A1:

    现在可以回答Q1 了,因为计算机是用补码表示的数字,如果采用原码0000 0000 和 1000 0000 分别代表+0 和 -0 ,那么取值范围应该是 [-127~127],反码同理,+0的反码是 0000 0000 ,-0 的反码是 1111 1111,那么对于反码是1000 0000 的负数,原码是 1111 1111 即 -127,所以取值范围还是[ -127, 127 ], 对于补码而言,+0 的补码是0000 0000,-0的补码等于反码 1111 1111 加1 就溢出了,所以-127 的补码 的补码是 反码 1000 0000 加1 ,1000 0001,那么反码1000 0000 用来代表谁呢,就-128 吧。

    A2:

    为什么计算机要用补码来表示数值呢? 最大的原因我觉得是为了计算方便,CPU被设计的时候只定义了加法,一个bit只有1跟0 ,0+0=0,1+0=1,1+1=10。如果负数以补码的方式存储,则加减运算做起来十分方便。至于同余以后再研究。
    所以 3+5= 0011 + 0101 = 1111 = 8
    3 - 5 = 0011 + 1011 = 1110[补码] = 1101[反码] = 1010 [原码] = -2

    -Share
    String为什么是不可变的
    \ No newline at end of file +Share
    String为什么是不可变的
    \ No newline at end of file diff --git "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" index 25b5ecb..9fed322 100644 --- "a/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" +++ "b/2016/03/07/String\344\270\272\344\273\200\344\271\210\346\230\257\344\270\215\345\217\257\345\217\230\347\232\204/index.html" @@ -13,4 +13,4 @@

    3. 怎么改变String的值?

    String的成员属性 private final char[] value 毕竟只是一个引用变量,它不可以指向其他对象实例,但是我们可以改变它当前指向的对象实例的值,通过反射。

    -Share
    JVM内存模型
    \ No newline at end of file +Share
    JVM内存模型
    \ No newline at end of file diff --git "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" index 78346cb..f995fbf 100644 --- "a/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" +++ "b/2016/05/11/JVM\345\206\205\345\255\230\346\250\241\345\236\213/index.html" @@ -20,4 +20,4 @@

    Share
    关于GC
    \ No newline at end of file +Share
    关于GC
    \ No newline at end of file diff --git "a/2016/06/09/\345\205\263\344\272\216GC/index.html" "b/2016/06/09/\345\205\263\344\272\216GC/index.html" index 3d83380..a7d0f0e 100644 --- "a/2016/06/09/\345\205\263\344\272\216GC/index.html" +++ "b/2016/06/09/\345\205\263\344\272\216GC/index.html" @@ -49,4 +49,4 @@

    Share
    线程 进程 并发 并行
    \ No newline at end of file +Share
    线程 进程 并发 并行
    \ No newline at end of file diff --git "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" index d082e38..16f48d4 100644 --- "a/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" +++ "b/2016/07/27/\347\272\277\347\250\213-\350\277\233\347\250\213-\345\271\266\345\217\221-\345\271\266\350\241\214/index.html" @@ -16,4 +16,4 @@

    Share
    也谈谈字符
    \ No newline at end of file +Share
    也谈谈字符
    \ No newline at end of file diff --git "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" index 562e88a..de8cec0 100644 --- "a/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" +++ "b/2016/08/07/\344\271\237\350\260\210\350\260\210\345\255\227\347\254\246/index.html" @@ -15,4 +15,4 @@

    UTF-32: 固定用四个字节表示一个字符
  • UTF-8:变长字节,用1-4个字节表示一个字符,是互联网传输编码用的最广泛的,隐含了赫夫曼编码思想,用最短的编码表示使用最频繁。
  • -
    Share
    好无聊啊~写写排序算法?
    \ No newline at end of file +Share
    笔记:关于TCP协议和IO的基础
    \ No newline at end of file diff --git "a/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" "b/2016/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" similarity index 59% rename from "2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" rename to "2016/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" index b4c9d0e..de41b1c 100644 --- "a/2017/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" +++ "b/2016/08/10/\347\254\224\350\256\260-\345\205\263\344\272\216TCP\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" @@ -1,4 +1,4 @@ -笔记:关于TCP协议和IO的基础 | 唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    +笔记:关于TCP协议和IO的基础 | 唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    1. TCP协议为什么比UDP可靠

    • 首先,TCP协议在传输数据前需要跟服务器进行握手,确保了服务器可以正常访问和回复。
    • 其次,TCP每次传输数据都要求对端确认,如果没有确认会重传。
    • @@ -22,4 +22,4 @@

      5. 为什么关闭要四次握手

      关闭不一定是四次握手,因为连接和关闭的机制原理其实是一样的,都是双端一应一答,只不过连接的时候把B端的应答放在一起了,而关闭理论上不放在一起是因为当A端告诉B端要关闭连接的时候,B端可能还有一些东西还要处理,比如说还有可能要发送一些数据给A端,所以只能先回复A的FIN,告诉它我收到连接了,等处理完了再发送FIN给A端。

      6. 端口到底是什么

      我指的是网络传输中虚拟的端口,显然只有在需要传输交互的时候才有端口的概念,所以端口可以看做是计算机给进程维护的一个与外部通信的标识号,比如说A程序要给另一台服务器的B进程发信息,找到服务器后,必须要通过一个标识才能知道要发给哪个进程。数据而端口正式这个标识。系统在为每个端口维护了一个队列,新来的数据只要放到对应队列里就可以了。

      为什么计算的端口通常最大是65535,因为在传输层的协议中Header Format最前端是Source Port和Destination Port,每个都是2个字节。所以说这是协议规定的,并不是什么物力资源限制。

      -
    Share
    \ No newline at end of file +
    Share
    好无聊啊~写写排序算法?
    \ No newline at end of file diff --git "a/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" "b/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" index 3d200c0..ed55476 100644 --- "a/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" +++ "b/2017/01/12/\345\245\275\346\227\240\350\201\212\345\225\212-\345\206\231\345\206\231\346\216\222\345\272\217\347\256\227\346\263\225\357\274\237/index.html" @@ -1,2 +1,2 @@ 好无聊啊~写写排序算法? | 唐佳写字的地方

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }
    -
    Share
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file +Share
    用wait和notify实现简单的生产-消费模式
    \ No newline at end of file diff --git "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" index da36037..8531b6d 100644 --- "a/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" +++ "b/2017/01/20/\347\224\250wait\345\222\214notify\345\256\236\347\216\260\347\256\200\345\215\225\347\232\204\347\224\237\344\272\247-\346\266\210\350\264\271\346\250\241\345\274\217/index.html" @@ -1,3 +1,3 @@ 用wait和notify实现简单的生产-消费模式 | 唐佳写字的地方

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    实验代码:

    -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Share
    谈谈线程中断
    \ No newline at end of file +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class ExWaitNotify {
    List<Object> products;
    int MAX = 50;
    public ExWaitNotify(){
    products = new ArrayList<>(30);
    }
    public ExWaitNotify(int num){
    products = new ArrayList<>(num);
    MAX = num;
    }
    public void produce(int num){
    synchronized (products){
    while (true){
    if (products.size() <= MAX - num){
    System.out.println("当前产品数量: "+products.size()+" 生产者 工作,生产"+num+"个产品");
    for (int i = 0; i < num; i++) {
    products.add(new Object());
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+" 生产者 唤醒消费者,生产者阻塞");
    products.notify();
    try {
    System.out.println("生产者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public void consume(int num){
    synchronized (products){
    while (true){
    if (products.size() >= num){
    System.out.println("当前产品数量: "+products.size()+" 消费者 工作,消费"+num+"个产品");
    for (int i = 0,k = products.size(); i < num; i++,k--) {
    // int a =;
    // System.out.println(a);
    products.remove(k-1);
    }
    }else {
    System.out.println("当前产品数量: "+products.size()+",不够 消费者 一次消费:"+num+" ,消费者 唤醒生产者生产");
    products.notify();
    try {
    System.out.println("消费者阻塞,等待");
    products.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[] args) {
    ExWaitNotify exWaitNotify = new ExWaitNotify(50);
    Thread produceThread = new Thread(() -> exWaitNotify.produce(20));
    produceThread.setName("produce");
    Thread consumeThread = new Thread(() -> exWaitNotify.consume(10));
    consumeThread.setName("consume");
    consumeThread.start();
    produceThread.start();
    }
    }
    Share
    谈谈线程中断
    \ No newline at end of file diff --git "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" index d32c144..61fd421 100644 --- "a/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" +++ "b/2017/02/01/\350\260\210\350\260\210\347\272\277\347\250\213\344\270\255\346\226\255/index.html" @@ -11,4 +11,4 @@

    Thread.Interrupted()

    类的静态方法,判断当前线程的中断状态,但是它跟 new Thread().isInterrupt() 的区别是后者只判断中断标识时候激活,而前者除了判断,还会清除当前中断标志。

    实验代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    public class ExStopThread{
    boolean stopSignal = false;
    public void stopThread(){
    this.stopSignal = true;
    }
    // 线程会在第五秒的时候推出方法
    public synchronized void stopBySignal(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    break;
    }
    }
    }
    //在第五秒的时候线程休眠或阻塞 并不会退出方法
    public synchronized void stopBySignal2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && stopSignal == true){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    break;
    }
    }
    }
    // 改进上述方法 在第五秒的时候 即使sleep 也能被中断
    public synchronized void testInterrupt(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.currentThread().isInterrupted()){
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    // e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    // interrupt 并不会推出线程,他只是为线程加上了 中断标志,需要在安全的地方的手动判断 isInterrupt 为true 推出线程。
    public synchronized void testInterrupt2(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    }
    }
    public synchronized void testInterrupted(){
    int count = 0;
    long start = System.currentTimeMillis();
    while (true){
    while (System.currentTimeMillis() - start >1000){
    System.out.println(Thread.interrupted());
    start = System.currentTimeMillis();
    System.out.println(Thread.currentThread().getName()+" is still running "+count);
    count++;
    }
    if(count == 5 && Thread.interrupted()){
    try {
    Thread.sleep(100000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
    break;
    }
    break;
    }
    }
    }
    public static void main(String[] args) {
    ExStopThread exStopThread = new ExStopThread();
    Thread threadA = new Thread(()->{
    exStopThread.stopBySignal();
    exStopThread.testInterrupt();
    exStopThread.testInterrupt2();
    exStopThread.testInterrupted();
    });
    threadA.setName("A");
    threadA.start();
    exStopThread.stopThread();
    threadA.interrupt();
    Thread.interrupted();
    }
    }

    -Share
    笔记:关于协议和IO的基础
    \ No newline at end of file +Share
    笔记:关于协议和IO的基础
    \ No newline at end of file diff --git "a/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" "b/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" index 4b8b3d0..cea8dfd 100644 --- "a/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" +++ "b/2017/02/10/\347\254\224\350\256\260-\345\205\263\344\272\216\345\215\217\350\256\256\345\222\214IO\347\232\204\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -笔记:关于协议和IO的基础 | 唐佳写字的地方 \ No newline at end of file +笔记:关于协议和IO的基础 | 唐佳写字的地方 \ No newline at end of file diff --git a/about/index.html b/about/index.html index 9845bfb..89ba424 100644 --- a/about/index.html +++ b/about/index.html @@ -1,2 +1,3 @@ - | 唐佳写字的地方 \ No newline at end of file + | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/09/index.html b/archives/2015/09/index.html index fc48819..9c7d198 100644 --- a/archives/2015/09/index.html +++ b/archives/2015/09/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2015/index.html b/archives/2015/index.html index fc48819..9c7d198 100644 --- a/archives/2015/index.html +++ b/archives/2015/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/02/index.html b/archives/2016/02/index.html index ad1eaac..fa22d01 100644 --- a/archives/2016/02/index.html +++ b/archives/2016/02/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/03/index.html b/archives/2016/03/index.html index 60ce3da..8d66ba7 100644 --- a/archives/2016/03/index.html +++ b/archives/2016/03/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/05/index.html b/archives/2016/05/index.html index 5ff4698..dbbfc95 100644 --- a/archives/2016/05/index.html +++ b/archives/2016/05/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/06/index.html b/archives/2016/06/index.html index 12edb4b..23617a9 100644 --- a/archives/2016/06/index.html +++ b/archives/2016/06/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/07/index.html b/archives/2016/07/index.html index e658015..3cba476 100644 --- a/archives/2016/07/index.html +++ b/archives/2016/07/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/08/index.html b/archives/2016/08/index.html index 3913a21..57f3190 100644 --- a/archives/2016/08/index.html +++ b/archives/2016/08/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2016/index.html b/archives/2016/index.html index 152aafc..7e2fa68 100644 --- a/archives/2016/index.html +++ b/archives/2016/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/01/index.html b/archives/2017/01/index.html index 3fac7d7..4ba6067 100644 --- a/archives/2017/01/index.html +++ b/archives/2017/01/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/02/index.html b/archives/2017/02/index.html index 10e520c..0cf3526 100644 --- a/archives/2017/02/index.html +++ b/archives/2017/02/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/08/index.html b/archives/2017/08/index.html deleted file mode 100644 index 4ff019d..0000000 --- a/archives/2017/08/index.html +++ /dev/null @@ -1 +0,0 @@ -Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/2017/index.html b/archives/2017/index.html index 0f809e5..1680d5e 100644 --- a/archives/2017/index.html +++ b/archives/2017/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/index.html b/archives/index.html index 3e66ae9..a5ffbf6 100644 --- a/archives/index.html +++ b/archives/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/archives/page/2/index.html b/archives/page/2/index.html index a34fc8c..6e84c68 100644 --- a/archives/page/2/index.html +++ b/archives/page/2/index.html @@ -1 +1 @@ -Archive | 唐佳写字的地方 \ No newline at end of file +Archive | 唐佳写字的地方 \ No newline at end of file diff --git a/index.html b/index.html index ddc729a..8dafdd7 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -唐佳写字的地方

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    Read More

    笔记:关于协议和IO的基础

    Read More

    谈谈线程中断

    Read More

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Read More

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }

    Read More

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Read More

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Read More

    关于GC

    先来看三个问题:

    Read More

    JVM内存模型

    JVM内存图

    Read More

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Read More

    \ No newline at end of file +唐佳写字的地方

    笔记:关于协议和IO的基础

    Read More

    谈谈线程中断

    Read More

    用wait和notify实现简单的生产-消费模式

    一个很简单的waitnotify的例子,wait和sleep的区别是前者会释放锁才进入休眠状态,而后者不释放锁,值得注意的是执行 notify 后,线程并不会立即释放锁,而是要等到退出 synchronized 后才释放锁或者自己主动释放锁(wait())。

    Read More

    好无聊啊~写写排序算法?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    public class ArraySort {
    /**
    * 直接插入排序 最坏复杂度 n2
    * 每一次都插入到一个已排序的序列中 稳定的排序
    * @param array
    * @return
    */
    public static int[] straightInsertionSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 1;i < array.length; i++) {
    for (int j = 0; j < i; j++) {
    if (array[i]<array[j]){
    int t = array[i];
    for (int k = i; k > j; k--) {
    array[k] = array[k-1];
    }
    array[j] = t;
    continue;
    }
    }
    }
    return array;
    }
    /**
    * 希尔排序 插入排序的一种
    * @param array
    * @return
    */
    public static int[] shellSort(int[] array){
    // 增量gap
    for (int gap = array.length/2; gap > 1 ; gap/=2) {
    // 直接插入排序
    for (int i = 0; i < gap; i++) {
    for (int j = i+gap; j < array.length; j += gap) {
    if (array[j] < array[i]){
    // 插入 后面的向后移动
    int t = array[j];
    // for ()
    }
    }
    }
    }
    return array;
    }
    /**
    * 平均n*lgn 最坏n2
    * @param array
    * @return
    */
    public static int[] quickSort(int[] array){
    quickSort1(array,0,array.length-1);
    return array;
    }
    public static void quickSort1(int[] array,int left,int right){
    if (left>=right){
    return;
    }
    int baseValue = array[left];
    int baseIndex = left;
    while (left<right){
    while (array[right] >= baseValue && left < right)
    right--;
    while (array[left] <= baseValue && left < right)
    left++;
    swap(array,left,right);
    }
    // swap(array,baseIndex,left);
    array[baseIndex] = array[left];
    array[left] = baseValue;
    quickSort1(array,baseIndex,left);
    quickSort1(array,left+1,right);
    }
    // public static void quickSort1(int[] array,int start,int end){
    // System.out.println(start+" "+end);
    // if (start == end){
    // return ;
    // }
    // int i = start + 1;
    // int j = end;
    // int baseValue = array[start];
    // while (i<j){
    // while (array[j]>=baseValue){
    // j--;
    // }
    //
    // while (array[i]<baseValue && i<j){
    // i++;
    // }
    //
    // System.out.println(i+" "+j);
    // swap(array,i,j);
    // }
    // swap(array,start,i);
    // quickSort1(array,start,i);
    // quickSort1(array,i+1,end);
    // }
    /**
    * 冒泡 n2
    * @param array
    * @return
    */
    public static int[] bubbleSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length-1; i++) {
    for (int j = array.length-1; j > i; j--) {
    if (array[j]<array[j-1]){
    swap(array,i,j);
    }
    }
    }
    return array;
    }
    /**
    * 选择排序 n2 每次选择最小的 也算冒泡的一种 但是减少了交换次数,只有n-1次交换。
    * @param array
    * @return
    */
    public static int[] selectSort(int[] array){
    if (array == null){
    return array;
    }
    for (int i = 0; i < array.length -1; i++) {
    int minIndex = i;
    for (int j = i+1; j < array.length; j++) {
    if (array[minIndex] > array[j]){
    minIndex = j;
    }
    }
    if (minIndex != i){
    swap(array,i,minIndex);
    }
    }
    return array;
    }
    /**
    * 计数排序 n 但是对数字有要求
    * @param array
    * @return
    */
    public static int[] countSort(int[] array){
    int maxIndex = 0;
    for (int i = 1; i < array.length; i++) {
    if (array[maxIndex] < array[i]){
    maxIndex = i;
    }
    }
    int[] array1 = new int[array[maxIndex]+1];
    for (int i = 0; i < array.length; i++) {
    array1[array[i]]+=1;
    }
    int[] newArray = array;
    int index = 0;
    for (int i = 0; i < array1.length; i++) {
    for (int j = 0; j < array1[i]; j++) {
    newArray[index++] = i;
    }
    }
    return newArray;
    }
    /**
    * 归并排序
    * @param array
    */
    public static int[] mergeSort(int[] array){
    // divice(array,0,array.length-1);
    mergeSort1(array,0,array.length-1);
    return array;
    }
    public static void mergeSort1(int[] array,int left,int right){
    int mid = (left+right)/2;
    if (left<right){
    mergeSort1(array,left,mid);
    mergeSort1(array,mid+1,right);
    mergeArray(array,left,right);
    }
    }
    public static void mergeArray(int[]array,int left,int right){
    int[] tmp = new int[right-left+1];
    int mid = (left+right)/2;
    int index = 0;
    int i = left;
    int j = mid+1;
    while (i<=mid && j<=right){
    if (array[i] < array[j]){
    tmp[index++] = array[i++];
    }else {
    tmp[index++] = array[j++];
    }
    }
    // 把左边的放入tmp
    while (i<=mid){
    tmp[index++] = array[i++];
    }
    while (j<=right){
    tmp[index++] = array[j++];
    }
    for (int k = 0; k < tmp.length; k++) {
    array[left++] = tmp[k];
    }
    }
    // public static void merge(int[] array,int left,)
    static void swap(int[] array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    public static void printArray(int[] t){
    if (t == null){
    System.out.println(t);
    return;
    }
    for (int i = 0; i < t.length; i++) {
    System.out.print(t[i]+" ");
    }
    System.out.println();
    }
    public static void main(String[] args) {
    int[] array = RandomUtil.randomIntArray(100,10);
    printArray(array);
    // int[] array1 = {43, 74, 72, 9, 10, 43 , 93 , 15 ,36 ,0 };
    // bubbleSort(array);
    // printArray(countSort(array));
    printArray(mergeSort(array));
    printArray(array);
    // printArray(straightInsertionSort(array));
    // printArray(array);
    }
    }

    Read More

    笔记:关于TCP协议和IO的基础

    java nio这块看了很多次,但是每次都是粗浅的看了下大概,导致很多东西回头又忘了,再加上现在nio这块现在容器封装的太深,你在平时根本就没有接触的机会。所以,要能记住不常用的东西,最简单办法就是从底层上理解他。

    Read More

    也谈谈字符

    1.计算机只认识字节

    计算机其实只存储和处理字节bit,对它而言,根本没有字符这个概念,字符是给人理解的,也就是说,字符都是在内存中才形成的,在硬盘上只有字节。

    Read More

    线程 进程 并发 并行

    任务调度

    线程是什么?要理解这个概念,须要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式,也就是说一个任务执行一小段时间后强制暂停去执行下一个任务,每个任务轮流执行。任务执行的一小段时间叫做时间片,任务正在执行时的状态叫运行状态,任务执行一段时间后强制暂停去执行下一个任务,被暂停的任务就处于就绪状态等待下一个属于它的时间片的到来。这样每个任务都能得到执行,由于CPU的执行效率非常高,时间片非常短,在各个任务之间快速地切换,给人的感觉就是多个任务在“同时进行”,这也就是我们所说的并发(别觉得并发有多高深,它的实现很复杂,但它的概念很简单,就是一句话:多个任务同时执行)

    Read More

    关于GC

    先来看三个问题:

    Read More

    JVM内存模型

    JVM内存图

    Read More

    String为什么是不可变的

    1. 为什么String 是不可变的?

    通过查看String的源代码发现,String的底层实现是通过一个 ==private final char[] value==; 也就是一个字符数组实现的,value 是一个引用,一旦指向堆中一个对象实例(数组也是一个对象)就不能再指向其他对象了,并且String并没有提供 setValue 方法,所以无法操作这个数组内存实例,所以String是不可变的。

    Read More

    \ No newline at end of file diff --git a/page/2/index.html b/page/2/index.html index 7496bcd..fc22a61 100644 --- a/page/2/index.html +++ b/page/2/index.html @@ -1 +1 @@ -唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Read More

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Read More

    \ No newline at end of file +唐佳写字的地方

    原码反码补码

    Q1. 为什么8位带符号的int 取值范围是[-128 ~ 127] ?

    Q2. 为什么计算机表示带符号的数值要用补码?

    1. 机器数和真值

    机器数就是一个数在计算机中的二进制形式,最高位0代表正数,1代表负数。
    真值就是这个机器数在计算机中所代表的值
    例如:
    1000 0001[机器数] = -1 [真值]

    Read More

    Http,Servlet,Servlet Contaniner

    前记:刚学Java Web的时候,大部分人都是先接触的Servlet,然后用web.xml配置了几个小demon,知道了只要在前端中调用后台的方法与配置文件中一致,后台就能请求响应,并传达响应,然后又马上学SSH框架,写了各种xxx.action,xxx.do,对Servlet的原理已经越来越模糊。

    Read More

    \ No newline at end of file diff --git a/tags/JVM/index.html b/tags/JVM/index.html index 30bedbf..25776b4 100644 --- a/tags/JVM/index.html +++ b/tags/JVM/index.html @@ -1 +1 @@ -JVM | 唐佳写字的地方 \ No newline at end of file +JVM | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/Java\345\237\272\347\241\200/index.html" "b/tags/Java\345\237\272\347\241\200/index.html" index 1c8f5d0..d4255d2 100644 --- "a/tags/Java\345\237\272\347\241\200/index.html" +++ "b/tags/Java\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -Java基础 | 唐佳写字的地方 \ No newline at end of file +Java基础 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" index 8f460a9..3caab4e 100644 --- "a/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ "b/tags/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" @@ -1 +1 @@ -字符编码 | 唐佳写字的地方 \ No newline at end of file +字符编码 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\345\271\266\345\217\221/index.html" "b/tags/\345\271\266\345\217\221/index.html" index 47a0e39..3ffb3cc 100644 --- "a/tags/\345\271\266\345\217\221/index.html" +++ "b/tags/\345\271\266\345\217\221/index.html" @@ -1 +1 @@ -并发 | 唐佳写字的地方 \ No newline at end of file +并发 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" "b/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" index 3df0a23..27bdaf9 100644 --- "a/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" +++ "b/tags/\346\216\222\345\272\217-\347\256\227\346\263\225/index.html" @@ -1 +1 @@ -排序 算法 | 唐佳写字的地方 \ No newline at end of file +排序 算法 | 唐佳写字的地方 \ No newline at end of file diff --git "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" index ee561fe..215c5a0 100644 --- "a/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" +++ "b/tags/\350\256\241\347\256\227\346\234\272\345\237\272\347\241\200/index.html" @@ -1 +1 @@ -计算机基础 | 唐佳写字的地方 \ No newline at end of file +计算机基础 | 唐佳写字的地方 \ No newline at end of file From 00ae9bfd32c6dcdb867717a18f24a71294a9dc26 Mon Sep 17 00:00:00 2001 From: tangjia Date: Mon, 13 Feb 2017 15:58:09 +0800 Subject: [PATCH 15/17] Site updated: 2017-02-13 15:58:08 --- about/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/about/index.html b/about/index.html index 89ba424..b0859fd 100644 --- a/about/index.html +++ b/about/index.html @@ -1,3 +1,4 @@ - | 唐佳写字的地方

    follow me on github + | 唐佳写字的地方 \ No newline at end of file From a790ba2483faea32fe2e9ec171cd36e6577ad9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E4=BD=B3?= Date: Mon, 13 Feb 2017 15:58:45 +0800 Subject: [PATCH 16/17] Create CNAME --- CNAME | 1 + 1 file changed, 1 insertion(+) create mode 100644 CNAME diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..9cd4b9d --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +immrtang.com From 0a9f45d84abf05d98d4637166e5f2b3fbd80fd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E4=BD=B3?= Date: Mon, 15 Jun 2020 20:35:45 +0800 Subject: [PATCH 17/17] Delete CNAME --- CNAME | 1 - 1 file changed, 1 deletion(-) delete mode 100644 CNAME diff --git a/CNAME b/CNAME deleted file mode 100644 index 9cd4b9d..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -immrtang.com