java SE19 火推


SE 19



前一天作业

实现图书管理系统, 通过集合存储,  并通过对象流, 
将图书信息存储到本地硬盘中, 在程序每次启动时, 再将数据载入程序中 !


------------


图书 Book

图书的编号   id
图书的名称   name
图书的内容简介 info

ArrayList<Book> books = new ArrayList<Book>();

HashMap

线程

进程与线程的区别 了解
一个应用程序, 一般是一个进程, 或多个进程 .

一个进程中 包含多个流程需要同时进行, 同时进行的每一个流程 , 我们 称其为程序的线程

线程实际上 是在进程基础上进行了划分, 一个进程可以包含一个 或 多个线程 !

早期的操作系统, 都是单进程系统 !

多线程的操作, 也正是Java的一大优势 , 

    -   Java是少有的支持多线程的语言

    -   Java执行多线程操作 极其简单 !



上面都是简介;

定义: **

进程:  一个完成独立运行的程序 称为一个进程( 在系统中拥有自己独立的内存空间)
线程:  是进程中的一条执行路径, 与其他线程共享进程中的内存空间 , 线程之间可以自由切换, 并发执行!


    一个进程至少要包含一个线程, 如果一个进程中不存在任何线程的话, 那么它对于系统来说, 就是一个垃圾进程, 会被系统(windows等)回收!
多线程程序, 是如何实现并发执行的? *
CPU 核心:   单个CPU核心, 只能同时执行一件事情!

时间片段:   不是程序在获取时间片, 而是程序中的线程在获取 !

    每个线程在争抢时间片, 得到时间片后, 进行执行!

线程的实现

一个方法被某个线程调用后,  则此方法在被调用线程中执行 !
方式一 通过继承Thread类 **
通过继承Thread的类, 重写run方法, 来完成线程逻辑的编写 !

    class MyThread extends Thread {

        @Override
        public void run() {
            //新的流程 , 线程的执行 其实就是执行run方法
            for (int i = 0; i <1000; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("董飞在看手机~");
            }
        }
    }

线程的执行应通过调用start方法来执行 ,而不是调用run方法 !
方式二:通过实现Runnable接口, 将其传递到Thread构造方法中***
使用的是 , Thread类的一参构造器: 

public MyThread implements Runnable{
    public void run(){}
}

Thread t = new Thread(new MyThread());
t.start();
上述两种方法, 哪种更合适:
Thread类 使用了一种设计模式 (代理设计模式) , 其实Thread内部, 无论使用哪种方法,  其实都是在操作Runnable的实现类!  而Thread本身 可以认为就是一个代理 !

也就是说 在性能上, 其实是一致的! 

我们建议大家更多的时候, 采用Runnable接口实现的方式来完成线程的编写 , 也就是方式二! 

    好处:  *

        -   使用Runnable 可以避免Java中单继承的局限 !
        -   因为Java中传递引用值的原因, 可以实现一个Runnable对象 , 传递给多个Thread构造方法,用来实现数据的共享 !
特殊的编写方式*****
其实在正常的开发中, 我们编写一个线程,  并不需要 ,也不想继承某个已存在的实体类 !  并且也很少进行多线程数据的共享操作 !

其实我们在程序中 很多多线程的操作, 都是编写完毕, 只执行一次 ! 

那么其实第二种的优势 并不大, 我们有时候为了更方便的编写, 一般使用匿名内部类的方式, 来操作第一种格式: 

new Thread(){
    public void run(){}
}.start();
常用方法
1.  start() *****

        开启一个线程,  并在新的线程中执行run方法 !

2.  static sleep(毫秒)***** (更多是为了演示特殊效果,在正常工作时, 很少通过休眠降低线程的活跃度)

        这个方法是一个静态方法, 哪个线程调用 哪个线程进行休眠 ,  放弃争抢时间片 ! 

3.  static yield(): 让出本次抢到的CPU时间片 !

4.  interrupt(): 中断线程  
        在线程上添加中断标记, 会触发异常!
        如果想杀死一个线程, 需要让线程杀死自己 !

5.  setPriority(int i) 设置线程的优先级

6.  static currentThread();获取当前代码所执行的线程对象 ***

7.  String getName():获取线程的名称

8.  setName(String name):设置线程的名称

9.  setDaemon(boolean isDaemon); 设置守护线程  *
线程优先级
一个线程的默认优先级是与调用自身线程优先级相等的 !

主线程在启动时的优先级为默认 !

通过setPriority 设置线程的优先级

可选择的值:  

    1:  较低的优先级
    5:  默认的优先级
    10: 较高的优先级

线程优先级调高以后, 并不能一定的保证 必然能抢到时间片 ! 只是提高了一丁丁的概率 ~
用户线程与守护线程
setDaemon(boolean daemon);
    参数:  是否设置一个线程为守护线程!  true表示是        


当一个程序, 不存在任何的执行的用户线程 , 则程序死亡 !
守护线程: 
    当程序中不存在用户线程时 , 守护线程无论是否执行完毕,  自动消亡 !
    GC的线程  就是一个守护线程 !
native
被成为JNI(Java Native Interface) , 本地自然接口 !  主要是用来调用计算机操作系统中的库函数 !
面试题: *****
Java中存在单线程程序吗?  

答案:

    Java中不存在单线程程序, 每一个Java软件执行后, 都最少要同时执行两个流程: 

    1.  JVM执行我们的代码
    2.  GC进行垃圾的回收
重点:
今天真正的重点, 其实不是在编码上, 而是在思想上, 

1.  如何更快的理解 两个或多个流程同时执行 ~

2.  如果将一段程序, 通过多个流程去更快的完成 ~ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值