1. 多线程:
(1) 多线程,同一时间,做多件事情
(2) 同一个时间点,只能做一件事情
(3) 同步与异步
2. Java中的多线程:
从main方法入口,启动Main线程,两种多线程实现方式
(1) 继承Thread类
(2)实现Runnable接口,这个是推荐使用
原因:
(1) Java是单继承,可以实现多个接口
(2) Runnable本身是任务的概念
3. 进程与线程:
(1) 进程:CPU分配资源的最小单位
(2) 线程:本身不占用资源,但是要消耗进程分配的资源
(3) 一个应用进程有多个进程,一个进程有多个线程
4. 生命周期
(1) 状态:
a. 新建状态(New):创建一个线程对象
b.就绪状态(Runnable):线程对象创建后,其他线程调用该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权
c.运行状态(Running):就绪状态的线程获取CPU,执行程序代码
d. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态
e.等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中(wait会释放持有的锁)
f.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中
g.其他阻塞:运行的线程执行sleep()或join()方法,或者发出I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
h.死亡状态(Dead):线程执行完了或者因异常退出run()方法,该线程结束生命周期
(2) 常用方法
a. 静态方法:sleep()\yield()
b. 普通方法:join()、wait()、notify()、notifyAll()、setPriority()、currentThread()
5. 线程同步和线程通信
(1) 线程同步:将操作共享数据的代码作为一个整体,同一时间只允许一个线程执行,执行过程中其他线程不能参与执行。
目的:防止多个线程访问一个数据对象时,对数据造成的破坏
① 同步方法:与有可能发生资源共享的方法添加synchronized关键字修饰
Public synchronized void run(){}
② 同步代码块:有可能发生资源共竞的代码块,给它加一个同步锁,即在代码块前添加synchronized来修饰
Synchronized (obj){}
③同步锁(Lock):Lock对象与资源对象同样具有一对一的关系
Class XX{
//显示定义Lock同步锁对象,此对象与共享资源具有一对一关系
Private final Lock lock=new ReentrantLock();
Public void mx{
//加锁
Lock.lock();
//需要进行线程安全同步的代码
//释放同步锁
Lock.unlock();
}
}
(2) 线程通信:
① Wait():导致当前线程等待并使其进入到等待阻塞状态。知道其他线程调用该同步锁对象的notify()或notifyAll()方法来唤醒此线程
② Notify():唤醒在此同步锁对象上等待的单个线程,如果有多个线程都在此同步锁对象等待,则会任意选择其中某个线程进行唤醒操作,只有当前线程放弃对同步锁对象的锁定,才可能执行被唤醒的线程.
③ notifyAll():唤醒在此同步锁对象上等待的所有线程,只有当前线程放弃对同步锁对象的锁定,才可能执行被唤醒的线程
这三个方法都是Object中的方法,必须与synchronized一起使用
Wait()与sleep()区别:
1) wait()是Object类的方法,sleep()是Thread类的静态方法
2) Wait()必须与synchronized一起使用,sleep()则不用
3) Wait()完,线程进入等待队列,而sleep()完,线程会进入阻塞队列
4) Wait()方法会释放同步锁,而sleep()则不会释放同步锁
5)都会抛出InterruptedException