概念
- 多线程是指在同一个进程中同时存在几个执行体,按几条不同的执行路径同时工作的情况。
- 线程不能独立存在,因为线程是为了减少不必要的系统负担引入的进程的下一级单位。
线程的优先级和调度
优先级
java语言中线程的优先级从低到高以整数1~10表示。Thread类有三个关于优先级常量:MIN_PRIORITY表示最小优先级,通常为1;MAX_PRIORITY表示最高优先级,通常为10;NORM_PRIORITY表式普通优先级,默认值为5。
调度
1 . 分时模型
CPU资源按照时间片分配,线程只能在指定的时间片内执行,一旦时间片使用完毕,就必须让出资源。
2 . 抢占模型
低优先级会为高优先级的线程让出执行权,但为了使低优先级的线程有机会执行,高优先级的线程应该不时地进入“睡眠”状态。java语言支持的就是抢占式调度模型。
利用Thread类的子类来创建线程
- 此类必须继承自Thread类
- 线程所执行的代码必须写在run()方法内(一般使用start()方法来启动线程)
构造方法
public Thread() 使用这个构造方法,必须创建Thread类的一个子类并且覆盖其run()方法
public Thread(String name) 创建一个线程对象,参数name制定了线程的名称 public Thread(Runnable target) 参数target的run()方法将被线程对象调用作为其执行代码。 常用方法
- currentThread() 返回当前正在执行的线程对象
- String getName() 返回线程的名称
- void start() 使该线程由新建状态变为就绪状态
- void run() 线程应执行的任务
- void join() 暂停当前线程的执行,等待调用该方法的线程结束后再继续执行本 线程
- void sleep(long m) 为当前执行的线程指定睡眠时间
- void yield() 暂停当前线程的执行,但该线程仍处于就绪状态,不转为阻塞状态
利用Runnable接口来创建线程
- 自己定义一个类,并实现Runnable接口,然后将这个类所创建的对象作为参数传递给线程的构造方法
- Runnable接口并没有任何对线程的指出,还必须创建Thread类的实例
- 想要多个同时激活的线程有序执行可以用join()方法,但要注意join方法会抛出InterruptedException类型的异常,要放入try-catch块内。
- 可以解决不能继承多个类的问题
- 可以轻松实现多个线程共享相同数据,只要用统一可运行对象为参数创建多个线程即可
多线程的同步控制
多个线程间共享相同的内存单元 -> 多个线程同时处理数据而使数据不一致
-> 处理数据的线程不能处理其他线程当前还没有处理结束的数据 -> “互斥锁”
互斥操作
synchronized关键字
- synchronized代码块中的代码越少越好,包含的范围越小越好,否则回事如多线程并发执行的很多优势
- 临界代码中的共享变量应定义为private型
- 对于一个static型的方法,如果为synchronized型,则必须整个类方法都为synchronized
线程之间的通信
void wait() | 如果一个正在执行同步代码的线程A执行了wait()调用(在对象x上),该线程暂停执行而进入对象x的等待队列,并释放已获得的对象x的互斥锁。线程A要一直等到其他线程在对象x上调用notify()或notifyAll()方法才能重新获得对象x的互斥锁后继续执行(从wait()语句后继续执行) |
void notify() | 唤醒正在等待该对象互斥锁的第一个线程 |
void notifyAll() | 唤醒正在等待该对象互斥锁的所有线程,具有最高优先级的线程首先被唤醒并执行 |