<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Java on LeoChu Space</title>
    <link>https://leochu.work/blog/tags/java/</link>
    <description>Recent content in Java on LeoChu Space</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sat, 29 Mar 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://leochu.work/blog/tags/java/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>jdk8和jdk8u有什么区别</title>
      <link>https://leochu.work/blog/tech/java/jdk8%E5%92%8Cjdk8u%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/</link>
      <pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/jdk8%E5%92%8Cjdk8u%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/</guid>
      <description>&lt;p&gt;JDK 8 代表的是一个大版本的更新，你可以理解成定义好了框架和实现&lt;/p&gt;
&lt;p&gt;JDK 8u代表的是基于JDK 8的后续小版本的迭代，里面不会有 JDK 8 标准之外的内容，只会包含一些安全性，性能等方面的修改，例如某个Class的实现优化&lt;/p&gt;
&lt;h3 id=&#34;观点一&#34;&gt;观点一&lt;/h3&gt;
&lt;p&gt;一般来说，建议选用大版本下面最新的u版本，比如你要选择 JDK 8 ，那么就选择 JDK 8u281，这个是目前8这个大版本的最新版本，原因是里面会修复和优化前序版本的一些问题&lt;/p&gt;
&lt;h3 id=&#34;观点二&#34;&gt;观点二&lt;/h3&gt;
&lt;p&gt;正常来说，应该使用OpenJDK8。&lt;/p&gt;
&lt;p&gt;OpenJDK8u是一些后期维护，一些特性并不是想要的。&lt;/p&gt;
&lt;h3 id=&#34;观点三&#34;&gt;观点三&lt;/h3&gt;
&lt;p&gt;对于jdk8u&lt;/p&gt;
&lt;p&gt;这个最新的免费版本号，其实包括了两个，8u201和8u202，这个就是JDK版本号的命名问题了。从2014年10月发布Java SE 7 Update 71(Java SE 7u71)开始，Oracle在发布Oracle JDK关键补丁更新(CPUs：Critical Patch Updates)的同时一般会发布相应的补丁集更新(PSUs：Patch Set Updates)。其中Oracle JDK关键补丁更新(CPUs)包含安全漏洞修复和重要漏洞修复，Oracle强烈建议所有Oracle JDK用户及时升级到最新的CPU版本，Oracle JDK 关键补丁更新(CPUs)版本号采用奇数编号。Oracle JDK补丁集更新(PSUs)包含相应CPUs中的所有修复以及其他非重要修复，仅当受到Oracle JDK关键补丁更新(CPUs)版本之外的其他漏洞的影响时才应当使用相应的补丁集更新 (PSUs)，Oracle JDK补丁集更新(PSUs)版本号采用偶数编号。因此，一般情况下我们只要下载奇数编号的最新版本更新就行了。&lt;/p&gt;
&lt;p&gt;简单来讲，Oracle将奇数版本作为BUG修正并全部通过检验的版本，Oracle官方建议用在生产环境最好使用这个版本。Oracle会在奇数版本之后同时发布一个偶数版本，偶数版本包含了奇数版本所有的内容，以及未被验证的BUG修复，Oracle官方建议，除非你受到未验证BUG影响，急需BUG修复才使用这个版本。因此，8u201是CPUs，关键补丁更新。8u202是PSUs，补丁集更新，推荐下载8u201。&lt;/p&gt;</description>
    </item>
    <item>
      <title>java代码的运行</title>
      <link>https://leochu.work/blog/tech/java/java%E4%BB%A3%E7%A0%81%E7%9A%84%E8%BF%90%E8%A1%8C/</link>
      <pubDate>Sat, 01 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/java%E4%BB%A3%E7%A0%81%E7%9A%84%E8%BF%90%E8%A1%8C/</guid>
      <description>&lt;h3 id=&#34;java-代码如何运行&#34;&gt;Java 代码如何运行&lt;/h3&gt;
&lt;p&gt;我们写的 Java 代码是高级语言，机器肯定是读不懂的。所以我们需要将它转换成机器能读懂的机器语言 (机器码)。 转换工作主要分为以下几个步骤：&lt;/p&gt;
&lt;h4 id=&#34;前端编译器&#34;&gt;前端编译器&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;javac&lt;/strong&gt; 就是前端编译器，可以将 java 文件编译成字节码组成的 class 文件。 java 代码如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Info&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;(String&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;复制代码
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行 &lt;strong&gt;javac Info.java&lt;/strong&gt; 生成 Info.class 文件, 再使用 &lt;strong&gt;javap -c Info.class 来&lt;/strong&gt;查看其中的字节码。&lt;/p&gt;
&lt;p&gt;class 中字节码内容如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230331151428.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230331151428.png&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;解释器和即时编译器&#34;&gt;解释器和即时编译器&lt;/h4&gt;
&lt;p&gt;我们通过 javac 将 java 文件编译成 class 文件，当 jvm 启动加载 class，需要逐条执行字节码指令来完成程序功能。但是程序的执行还是得在机器上，但是机器是不认识字节码的，所以我们需要将字节码转换成机器码，这样才能让机器执行程序。 &lt;em&gt;什么是机器码？&lt;/em&gt; 机器码就是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。 而解释器和即时编译器 (Just In Time Compiler，JIT) 就是 JVM 中将字节码转化为机器码的工具。&lt;/p&gt;
&lt;h5 id=&#34;解释器&#34;&gt;解释器&lt;/h5&gt;
&lt;p&gt;解释器是一行一行地将字节码解析成机器码，解释到哪就执行到哪，狭义地说，就是 for 循环 100 次，你就要将循环体中的代码逐行解释执行 100 次。当程序需要迅速启动和执行时，解释器可以首先发挥作用，省去编译的时间，立即执行。&lt;/p&gt;</description>
    </item>
    <item>
      <title>线程不安全的simpleDateFormat</title>
      <link>https://leochu.work/blog/tech/java/%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84simpledateformat/</link>
      <pubDate>Sat, 18 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84simpledateformat/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420183112.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420183112.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;1什么是线程不安全&#34;&gt;1.什么是线程不安全？&lt;/h2&gt;
&lt;p&gt;线程不安全也叫非线程安全，是指&lt;strong&gt;多线程执行中，程序的执行结果和预期的结果不符的情况就叫做线程不安全&lt;/strong&gt;。 ​&lt;/p&gt;
&lt;h3 id=&#34;线程不安全的代码&#34;&gt;线程不安全的代码&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;SimpleDateFormat&lt;/code&gt; 就是一个典型的线程不安全事例，接下来我们动手来实现一下。首先我们先创建 10 个线程来格式化时间，时间格式化每次传递的待格式化时间都是不同的，所以程序如果正确执行将会打印 10 个不同的值，接下来我们来看具体的代码实现：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.text.SimpleDateFormat;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.util.Date;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.util.concurrent.ExecutorService;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.util.concurrent.Executors;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SimpleDateFormatExample&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 创建 SimpleDateFormat 对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; SimpleDateFormat simpleDateFormat &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; SimpleDateFormat(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mm:ss&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;(String&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 创建线程池&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ExecutorService threadPool &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Executors.&lt;span style=&#34;color:#a6e22e&#34;&gt;newFixedThreadPool&lt;/span&gt;(10);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 执行 10 次时间格式化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; 10; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; finalI &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#75715e&#34;&gt;// 线程池执行任务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            threadPool.&lt;span style=&#34;color:#a6e22e&#34;&gt;execute&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Runnable() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;// 创建时间对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    Date date &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Date(finalI &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; 1000);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;// 执行时间格式化并打印结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(simpleDateFormat.&lt;span style=&#34;color:#a6e22e&#34;&gt;format&lt;/span&gt;(date));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            });
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们预期的正确结果是这样的（10 次打印的值都不同）：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
