Java day16

----------------------------------------------
线程

Thread类(线程类)
  1.线程的概念
      1).进程中多个同时执行的任务
      2).程序运行就是打开一个进程,进程中至少存在一个线程 - 主线程 main

  2.线程类创建的方式
      1)自定义线程类 - 继承 Thread
        a.自定义线程类,继承Thread
        b.重写run()
        c.创建线程对象
        d.start()开启线程
        结论: 一个类只能有一个父类,当他继承Thread,这个类就只能是线程类了,有局限性

      2).自定义任务类 - 实现Runnable接口
        a.自定义类任务类,实现Runnable接口
        b.重写run()
        c.创建任务类对象
        d.通过任务类对象,构造线程对象
        e.start()开启线程
        结论: 
            a.类除了可以实现Runnable接口,还可以继承其他类,和实现其他接口,没有太多的局限性
            b.在创建相同的任务线程时,任务对象可以重复使用

      3).匿名内部类创建线程类 - 结合(1)或(2)
          注意: 这不是一种创建方式,只是一种优化写法


  3.Thread常用API:
      1).currentThread() -> 获取当前线程对象
      2).getName() ->获取当前线程对象的名字
      3).getPriority() -> 获得线程优先级
         setPriority -> 设置线程优先级
             注意: 
               a.范围: 1 ~ 10 
                   数越大,优先级越高
               b.优先级只是改变cpu分配时间片的概率
      4).isDeamon() -> 询问是不是守护线程
          注意:
            守护线程 / 前台线程
            当所有的前台线程都结束之后,守护线程也会自动结束
            java中自带的守护线程 - GC

      5).Thread.sleep() -> 线程休眠指定时间

线程同步[线程安全]:
  1.产生的原因: 多个线程共享一个资源
  2.解决的办法: 使用同步锁(synchronized)
    (1)同步方法锁:
      a.只能同时被一个线程所持有,当线程执行完这个方法的时候,才会将锁释放
      b.锁范围越大,效率越低
      c.锁在方法上,实际上锁的还是this对象上加锁
      d.锁普通方法: this对象上加锁
        锁静态方法: 锁 类.class(类的字节码文件)对象

    (2)同步代码块:
      a.可以将一部分代码加锁, 同步代码锁,需要借助一个对象
      b.加锁的对象: 可以是任意对象,只需要确保是多个线程所共享(对象是唯一的)
      c.一般来说都会使用this表示对象
      d.同步锁(对象锁),一个对象只能加一把锁,并且只能同时被一个线程所持有的

  3.Lock锁 - 接口
    1).实现类 -> ReentreantLock(可重入锁)
    2).API:
      加锁: 锁对象.lock()
      解锁: 锁对象.unlock()
    3)乐观锁/悲观锁 -> 理解原理(使用场景)


线程状态:
  新建状态: new 一个对象
  就绪状态:
    a.通过调用start()进入就绪状态
    b.run()就绪:  时间片到期,归还/调用yeild()
  运行状态
    a.cpu分配时间片进入到运行状态
  阻塞状态(Blocked):
    a.join() -> 造成别的线程阻塞
    b.IO阻塞 -> 控制台输入/输出
    c.计时等待 -> sleep(100)/wait(100)
    d.无线等待 -> wait()/notifyAll()/notify()
    e.锁阻塞 -> 加上同步锁/Lock锁
  被终止状态: run()结束


线程通信:
  1.两个线程有共享资源,并且线程之间有动作交互
  2.实现: 使用wait() 和 notify()/notifyAll()
    notify() -> 唤醒线程,每次中能唤醒一个线程,只能唤醒在等待的线程
    notifyAll() -> 唤醒所有正在等待的线程

    注意:wait() 和 notify 需要放在同一个锁中

-----------------------------------------------------
线程池:
  1.概念:其实就是⼀个容纳多个线程的容器,其中的线程可以反复使⽤,省去了频繁创建线
程对象的操作,⽆需反复创建线程⽽消耗过多资源
  2.好处:节约内容,提高效率
  3.创建方式: 使用Executors 工厂类中的静态方法

    1).newCachedThreadPool() - 根据须需要创建线程池 
    2).newFixedThreadPool(int nThreads) - 创建固定数量的线程池
    3).newScheduledThreadPool(int corePoolSize) - 创建周期性执行的线程池
    4).newSingleThreadExecutor() - 创建单个线程的线程池

  4.Callable接口 -> 为了取代 Runnble
    1).Callable不能再Thread类中使用,只能在线程池中使用
    2).注意:
      a.submit() 会有返回值,Future
      b.使用 get()接收call()的返回值
         可能会遇到阻塞,需要一直等待
      c.使用get(long, TimeUnit) -> 超时等待


面试题:
  线程池有什么好处?
  为什么要使用线程池?
  线程池的创建方式 - 分别在什么场景下选择哪种线程池

_______________________________________
属性集: Properties
  1).特点:
    a.Properties是以键值对的方式进行存储
    b.但是键值对仅支持String类型的属性映射
    c.不能写在同一行
      //name=\u00E5\u00BC\u00A0\u00E4\u00B8\u0089"  sex \= M  id \= 123
      //代表后面都是值
        写在内存中然后store,使用get得到的字符显示不会有编码问题,如果在内部文件直接写中文,运行编译后文件中的值会显示utf-8编码对应的字节码值
        (今  -> \u00E4\u00BB\u008A)E4 BB 8A
        因为默认使用ISO8859-1编码(单字节的编码)
        所以控制台显示ä»三个字节码对应的字符(解码)
        所以应该System.out.println(new String(pro.getProperty("name").getBytes("ISO8859-1"),"utf-8"));
        先编码回去得到正确的字节码,然后使用对的编码方式去解码
        因为utf-8是默认的编码,可省略

  
  2)常用方法:
    a. void getProperty() -> 通过key获取value值
       void setProperty() -> 了解

    b.加载属性集(配置文件)
      void load(Reader)
      void load(InputStream)

    c.获取路径 - 可以直接放在src下
       方式一:
        xx.class.getClassLoader().getResource("相对路径").getPath();

       方式二:
        xx.class.getClassLoader().getResourceAsStream("相对路径");
_________________________________________
JDK1.8的新特性

Lambda表达式:函数式编程思想(c++ c#)
  1.语法结构:
    (参数列表) -> {逻辑代码}
      1). (参数列表): 表示要重写的抽象方法的参数列表
      2). ->: 表示固定语法(固定指向),指向/传递的意思
      3). {逻辑代码}: 要重写的方法代码
      4). 优化写法 - 既可推导可省略
        a. ()中参数类型,可以省略
          如果有多个参数类型,每个参数类型都要一起省略
        b. {}中如果代码只有一行,不论这个方法有没有返回值,那么【 {} return ;】都可以省略,而且必须一起省略

        c. ()中如果只有一个参数,()可以省略,和类型一起省略
           ()中如果没有参数,()必须写

使用前提:
  1.实现一个接口
  2.接口中只能有一个抽象方法
  3.接口是作为方法的参数使用


常用的函数式接口
  supplier:生产者
    抽象方法: T get()
    作用: 生产对象


  consumer:消费者
    抽象方法: void accept(T t)
    默认方法: andThen(Consumer) - 将两个消费组合在一起使用
    作用: 使用对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值