ObjectStream对象流&Properties类常用方法&Thread线程的创建方式和线程常用api

对象流

  • 序列化: Serialiaze 将java对象转换为二进制流ObjectOutputStream .writeObject(java对象)
  • 反序列化: 二进制流还原java对象ObjectInputStream .readObject() --> java对象

java中要支持序列化和反序列化,需要实现接口Serializable(标记接口)

seriaVersionUID序列化版本(序列号) 当对class类做修改时,seriaVersionUID就会变动,反序列化时就会报异常,可以把serialVersionUID固定,这样就不会出现异常了

class User implements Serializable{
    private static final long serivalVersionUID = 1L;//固定序列化版本
    String username;
    transient String pass;//瞬态的 
}

transient关键字修饰的成员变量是瞬时的

存储多个对象,读取的解决方法1

while(true){
    try{
        Object obj = ois.readObject();
        //如果出现了 EOFException 表示读到了对象流的末尾,就该退出循环
    }catch(EOFException e){
        break;
    }
}

解决方法2

  • 把多个对象存入集合,把集合作为整体写入对象流
  • 将来读取时只需要读一次,读到的是集合

Properties

Properties是专门用于读取和写入*.properties文件的类

//由于实现了Map接口所以它的文件内部都是键值对
key=value
classDiagram
Map <-- HashMap
Map <-- TreeMap
Map <-- LinkedHashMap
Map <-- Hashtable
Hashtable <|-- Properties

Hashtable是线程安全

HashMap不是线程安全的

Properties特有方法,特点是该类的键和值都被当做字符串

  • setProperty(String key,String value) : 添加 或修改
  • getProperty(String key) : 根据键找到对应的值 返回String value
  • stringPropertyNames() : 返回 Set 获取所有的键集合
  • load() 加载 (读取) *.properties文件的内容
    • load不会自动关流,需要手动关流
    • load既支持字节流,也支持字符流
  • store() 存储 (写入)把集合内容写到*.properties文件中
    • 既支持字节流,也支持字符流
    • store 第二个参数,表示properties中的注释信息

*.properties文件注释的格式

#注释内容 , 一般使用英文注解,

*.properties 文件一般用作"配置文件",将来存储容易改变的信息,它不会影响java代码

  • 数据库的用户名
  • 数据库密码

并行和并发

  • 进程 : 一个程序处于运行状态,就可以成为一个进程

  • 线程 : 一个进程是由一到多个线程组成, (java进程就是由main线程与垃圾回收线程

  • 它们都可以并行或并发的运行

  • 并行 : 多核cpu多个核同时运行代码

  • 并发 : 单核cpu单个核轮流执行多个代码片段

    • 宏观上,由于cpu在不同程序之间切换速度很快,造成"同时"效果
    • 微观上,cpu都是在交替执行的

创建线程

创建线程的三种方法
  • Thread : 继承Thread类 重写父类中的 run方法 (Thread类也是实现了Runnable接口的)
  • Runnable : 实现Runnable接口重写接口中的抽象方法
  • FutrueTask + Callable : 实现Callable 接口重写 call 方法 (唯一一个有返回值的线程)
才艺展示
//Thread 方法创建并启动线程
class MyThread extends Thread{
    //重写父类run方法
    public void run(){
        //该线程要执行的代码
    }
}
new MyThread().start() //启动线程
    

//Runnable 方法创建并启动线程
class MyRunnable implements Runnable{
    public void run(){
        //此线程要执行的代码
    }
}
new Thread(new Runnable()).start();//启动线程
//以上代码可以简化为匿名内部的方式
new Thread(new Runnable(){
    public void run(){
        //要执行的线程任务
    }
}).start();//创建并启动线程
//由于Runnable是函数式接口所以可以简化为Lambda表达式
new Threa(()->{
    //线程要执行的任务
}).start();//创建并启动线程


//FutureTask + Callable
class MyTask implements Callable<结果类型>{
    public 结果类型 call(){
        //此线程要执行的代码
    }
}
//FutrueTask用来接收Callable任务的返回结果
FutureTask task = new FutureTask(new MyTask());
//创建并启动线程
new Thread(task).start();
//获取该线程的返回值
结果类型 result = task.get();//等待线程运行结束,获取结果
三种创建线程的对比
  • Runnable : 扩展性好,更灵活,可以配合Lambda用,配合线程池
  • Callable : 特点与Runnable一样,多一个返回结果
  • 继承 Thread : 不能配合线程池使用

线程api

线程名称默认格式 : Thread-编号 ( 名称可以自定义方便调试)

//	使用 Runnable 方法创建线程并 自定义名字 
new  Thread(()->{线程要执行的代码}, "线程名称");

Thread.currentThread() : 得到当前线程对象

Thread.sleep(long 毫秒值) : 让当前线程不执行代码,让出cpu使用权,等休眠时间到了,在恢复运行

线程子类重写父类方法时不能抛出比父类 多 的异常
优先级相关方法

优先级返回( 1 ~ 10 )

  • setPriority(优先级) : 给予系统提示优先级 数值越大越有几率优先被执行
  • getPriority(); 返回此线程的优先级

此处设置的优先级只是给系统的提示,至于系统是否采纳取决与系统,main线程的优先级是5

垃圾回收线程的优先级最低

守护线程 (垃圾回收线程)
  • 守护线程会在其他线程结束后立刻结束
  • 正常线程,必须将自身的代码全部运行完才会结束
  • main属于正常线程,垃圾回收线程属于守护线程
  • setDeamon(true) : 将当前线程设置为守护线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值