多线程

进程

正在运行的应用程序

  • 系统进行资源分配和调用的独立单位
  • 每个进程都有内存空间和系统资源
线程

进程中的单个顺序控制流,一条执行路径

多线程实现方式

继承Thread类
  • 定义一个类继承自Thread类并重写run()方法
  • 创建类对象,启动线程 : start()
  • 重写run()方法:
    • run()是用来封装被线程执行的代码
  • run()和start()区别
    • run():封装线程执行的代码,直接调用,相当于普通方法的调用
    • start():启动线程;然后由JVM调用该线程的run()方法

设置和获取线程名称

  • void setName(String name):将此线程的名称更改为参数name
  • String getName():返回此线程的名称
  • currentThread():返回对当前正在执行的线程对象的引用

可选择重写构造方法来对线程进行命名

线程调度

线程具有两种调度模式

  • 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
  • 抢占式调度模型:优先让优先级高的线程使用CPU,如果优先级相同,随机选择。优先级高的线程获取的CPU时间片相对多一些

Java使用抢占式调度模型

Thread类中设置和获取线程优先级:

  • getPriority():返回此线程的优先级
  • setPriority(int newPriority):更改此线程的优先级 MIN-NORM-MAX:1-5-10

线程优先级高仅仅表示线程获取CPU时间片的几率高,并不是绝对性的优先运行

线程控制
  • sleep(long millis):使当前正在执行的线程暂停执行指定的毫秒数
  • join():等待该线程死亡
  • setDaemon(boolean on):将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
线程生命周期

线程生命周期

实现Runnable接口
  • 定义一个类实现Runnable接口,重写run()方法
  • 创建类对象,创建Thread类对象,把定义类对象作为构造方法的参数
  • 启动线程

好处:

  • 避免了Java单继承的局限性
  • 适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

线程同步

数据安全问题

  • 多线程、共享数据、多条语句操作共享数据
同步代码块

锁多条语句操作共享数据

synchronized(任意对象){
 多条语句操作共享数据的代码
}
同步方法

synchronized 关键字加到方法上

修饰符 synchronized 返回值类型 方法名( 方法参数 ){

}

同步方法锁的对象:this

同步静态方法:

修饰符 static synchronized 返回值类型 方法名( 方法参数 ){

}

同步静态锁对象:类名.class

线程安全

StringBuffer:

  • 线程安全,可变的字符序列

Vector:

  • 该类改进了List接口,Vector被同步。
  • 不需要线程安全可以使用ArrayList代替Vector

Hashtable:

  • 该类实现了一个哈希表,键值映射。任何非null对象都可以作为键或者值
  • 实现了Map接口,Hashtable被同步。
  • 不需要线程安全可以选择HashMap代替
Lock锁
  • lock():加锁
  • unlock():释放锁

Lock接口不能直接实例化,采用实现类ReentrantLock来实例化

  • ReentrantLock():创建一个ReentrantLock实例