Java基础-Java后端漫漫长路的伊始(4)
本文最后更新于 193天前,其中的信息可能已经有所发展或是发生改变。若对文章内容存疑,或是本文的转载部分侵犯了您的权益,请联系博主 3240572824@qq.com

多线程

线程 thread 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程的实际运作单位。

进程是程序的基本执行实体。

可以将进程理解为一个个软件,而软件的不同功能,就是一个个线程。多种不同功能(线程)同时进行,称之为多线程。

应用场景

只要期望多个事件同时运行就要用到多线程(例 软件中的耗时操作 所有的聊天软件 所有的服务器)

多线程两个概念

  • 并发:
    • 在同一时刻,有多个指令在单个CPU上交替执行
  • 并行:
    • 在同一时刻,有多个指令在多个CPU上同时执行
图片截自b站阿玮老师的Java课程视频,文章末尾已标明出处

Java中线程的六个状态及线程生命周期

  • NEW 新建状态 (创建线程对象)
  • RUNNABLE 就绪状态 (start方法)
  • BLOCKED 阻塞状态 (无法获得锁对象)
  • WAITING 等待状态 (wait方法)
  • TIMED-WAITING 计时等待 (sleep方法)
  • TERMINATED 结束状态 (全部代码执行完毕)
图片截自b站阿玮老师的Java课程视频,文章末尾已标明出处

多线程的三种实现方式

方式一

  1. 自己定义一个类继承Thread
  2. 重写run方法
  3. 创建子类对象 并启动线程

方式二

  1. 自己定义一个类实现Runnable接口
  2. 重写里面的run方法
  3. 创建自己类的对象
  4. 创建一个Thread类对象 并开启线程

方式三

  1. 自己定义一个类实现Callable接口
  2. 重写call(此方法有返回值,表示多线程运行的结果)
  3. 创建自定义类的对象(表示多线程要执行的任务)
  4. 创建FutureTask的对象(用于管理多线程运行的结果)
  5. 创建Thread类的对象并启动(即线程)

下面是通过方式二实现多线程的实例

public class MyRun implements Runnable{

    @Override
    public void run() {
        // 重写要执行的代码
        for (int i = 0; i < 10; i++) {
            // 不可以直接用getName()方法 因为MyRun类无此方法

            // 使用.currentThread()获取到当前线程的对象

            System.out.print(Thread.currentThread().getName()+"?   ");
        }
    }
}

// 创建MyRun对象 (多线程要执行的任务)
        MyRun run=new MyRun();

        // 创建线程对象
        Thread t1=new Thread(run);
        Thread t2=new Thread(run);
        t1.setName("t1");
        t2.setName("t2");

        t1.start();
        t2.start();
// t2?   t2?   t1?   t2?   t1?   t2?   t1?   t2?   t1?   t2?   t1?   t2?   t1?   t1?   t2?   t1?   t1?   t1?   t2?   t2?   

常见成员方法

图片截自b站阿玮老师的Java课程视频,文章末尾已标明出处

线程安全

我们由这个简单的场景引入问题:三个窗口(线程)同时售卖10张电影票,在未采取安全措施时,运行结果如下

窗口1卖出0
窗口1卖出1
窗口1卖出2
窗口1卖出3
窗口1卖出4
窗口1卖出5
窗口1卖出6
窗口1卖出7
窗口1卖出8
窗口1卖出9
窗口3卖出0
窗口3卖出1
窗口3卖出2
窗口3卖出3
窗口3卖出4
窗口3卖出5
窗口3卖出6
窗口3卖出7
窗口3卖出8
窗口3卖出9
窗口2卖出0
窗口2卖出1
窗口2卖出2
窗口2卖出3
窗口2卖出4
窗口2卖出5
窗口2卖出6
窗口2卖出7
窗口2卖出8
窗口2卖出9

原因:Java每个线程都是优先操作自己的工作区,而主内存更新数据有可能不及时。

两种同步代码块解决方法

同步代码块:将操作共享数据的代码锁起来。这样就可以避免数据不一致的问题。

  • 关键字synchronized
  • 锁 Lock

等待唤醒机制

又名生产者消费者模式,是一个十分经典的多线程协作模式,可实现线程轮流交替执行的效果。

线程池

核心原理

  1. 创建一个空池子
  2. 提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还池子(下一次再次提交任务时,无需创建新线程,直接复用已有线程)
  3. 但若提交任务时,池子中无空闲线程,也无法创建新线程,任务就要排队等待

两种创建方法

  • newCachedThreadPool() 创建一个无上限的线程池
  • newFixedThreadPool() 创建一个有上限的线程池

自定义线程池

用于更好地控制线程的创建和管理,以及优化线程的使用。

网络编程

在网络通信协议下,不同计算机上运行的程序,进行的数据传输。

三要素

IP

设备在网络中的地址,是唯一的标识。分为IPv4和IPv6,目前IPv4已经全部分配完毕。值得一提的是,IP127.0.0.1永远指向本机,即localhost。

端口号

应用程序在设备中的唯一标识。由两个字节表示的整数 0~65535,其中0~1023之间的端口号用于一些知名的网络服务或应用。

协议

数据在网络传输的规则 (常见协议有UDP TCP http https ftp),因为各自的特点不同,其适用场景不同。

JDBC

Java DataBase Connectivity,即Java语言操作关系型数据库的一套API。下面是通过JDBC操作Mysql数据库的示例。

// 1 导入驱动jar包

        // 2 注册驱动
        // Mysql5后 可以不写 jar包中已经有了 可自动加载驱动类类名
//        Class.forName("com.mysql.cj.jdbc.Driver");

        // 3获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/ember?useSSL=false&serverTimezone=UTC";
//        String url = "jdbc:mysql://127.0.0.1:3306/ember?useSSL=false";
        String username = "root";
        String password = "****";

        Connection con = DriverManager.getConnection(url, username, password);
        // 4 定义SQL语句
        String sql = "update score set gender='男' where name='张三'";
        // 5 获取SQL执行对象
        Statement s = con.createStatement();
        // 6 执行SQL
        // execute语句返回语句影响的行数
        int i = s.executeUpdate(sql);
        // 7 处理返回结果
        System.out.println(i);
        // 8 释放资源
        s.close();
        con.close();

常见API

  • Statement SQL语句对象 用于执行SQL语句,包括查询语句和更新语句,但存在SQL注入的风险
  • PreparedStatement 预编译语句 与Statement类似,但在执行之前先进行预编译,提高了执行效率和安全性
  • Connection 数据库连接对象 用于与数据库建立连接
  • DriverManager 驱动管理类 用于管理数据库驱动程序,负责加载和注册数据库驱动
  • ResultSet 结果集对象 获取查询语句的结果

反射

反射通过获取Class对象,实现对其成员变量,成员方法及构造方法等信息进行编程访问。

使用场景

  • 获取任意一个类中的所有信息
  • 结合配置文件动态创建对象

三种获取class对象的方式

  • Class.forName(“全类名”) (全类名:包名+类名)
    • 适用场景:最为常用
  • 类名.class
    • 适用场景:一般多用作参数
  • 对象.getClass()
    • 适用场景:已经存在此类的对象时

“在反射面前,一切都是透明的”

在Java的反射机制下,可以突破对象的封装性,访问和操作对象的私有成员,并且可以动态地获取和调用类的方法和属性,使得原本私有的、隐藏的信息变得透明可见。

“反射,框架的灵魂”

此回答来自GPT。

动态代理

无侵入式的给代码增加额外功能。

使用场景

  • AOP(面向切面编程) 通过动态代理可以在方法调用前后执行额外的逻辑,例如日志记录、性能监控等
  • 远程调用 通过动态代理可以将方法调用转发到远程服务器,实现远程方法调用
  • 延迟加载 通过动态代理可以在需要时动态地创建对象,从而实现延迟加载的效果

相关链接

后话

OK,Java基础的总结就差不多是这样了。对了,为什么说这只是个“伊始”,看看互联网大佬鱼皮的Java路线图吧。

最后,我将阿玮老师的一句话送与看到这里的你。

莫道桑榆晚,为霞尚满天

作者:Gaspard
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0协议
若是幸得赏识、转载,还请注明文章地址及作者哦~

评论

  1. Windows Chrome
    7 月前
    2023-9-21 11:42:39

    你好,看完你的博客文章,感觉很不错!希望与你网站首页友情链接
    大流量卡
    (已被屏蔽)
    专注于移动/联通/电信推出的大流量多语音活动长短期套餐手机卡的相关知识的介绍普及
    听说互换友情链接可以增加网站的收录量,特此来换,如果同意的话就给(已被屏蔽)发信息或者就在此回复下吧!

    来自湖北
    • 博主
      大流量卡
      Windows Chrome
      7 月前
      2023-9-21 19:24:12

      感谢赏识,但本站承诺不包含商业性质内容,望理解

      来自湖北

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇