目录
目录
一:线程与进程
进程:是程序的一次执行过程,是系统运行程序的基本单位
线程:是进程的一个执行单位,一个进程至少有一个线程
线程:
注意:
1.进程的执行取决于cpu的调度,我们是干涉不了的,因此多线程是随机的
2.java程序的进程至少包括两个线程,主进程main()方法,另一个是垃圾回收机制。
3.因为创建线程比创建进程开销小的多,因此我们通常创建的是多线程
二:线程的创建-继承方式
1.步骤:
(1)定义Thread类的自雷,重写run()方法
(2)创建Thread子类的实力,即创建了线程对象
(3)调用线程对象的start()方法来启动线程
public class MyThread extends Thread {/*** 重写 run 方法,完成该线程执行的逻辑*/@Overridepublic void run () {for ( int i = 0 ; i < 200 ; i ++ ) {System . out . println ( " 自定义线程正在执行! " + i );}}}
线程的执行流程:
线程内存图
2.run()方法和start()方法
run()方法,是线程执行的任务方法,每个线程都会调用run()方法执行,我们将线程要执行的任务都写在run()方法中就可以被线程调用执行。
start()方法: 开启线程,线程调用run()方法。
一个线程只能被启动一次,一次只能运行一个线程。
3.线程名字的设置和获取
Thread类的方法 String getName()可以获取线程的名字
Thread类的方法 setName(String name) 设置线程的名字
4.线程等待唤醒的方法
wait() | 当前线程等待,必须拥有此对象监视器 |
notify() | 唤醒在此对象监视器上等待的单个线程 |
notifyall() | 唤醒在此对象监视器上等待的所有线程 |
三:线程的创建-实现Runnable接口
1.步骤:
(1)定义Runnable接口的实现类,并重写该接口的run()方法
(2)创建Runnable实现类的实力,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象
(3)调用start()方法来启动线程
2.Runnable相比Thread的优势
(1)可以避免java单继承的局限性
(2)适合多个相同的程序代码共享一个资源
(3)代码可以被多个线程共享,实现解耦操作
四:线程安全
1.引发原因:
线程安全问题都是由全局变量及静态变量引起的,若每个县城中对全局变量、静态变量只有读操作,这个线程是安全,若多个线程同时执行写操作,可能会影响线程安全
2.同步代码块:
格式:
synchronized(同步锁){
需要同步操作的代码
}
3.同步方法:
public synchronized void method(){ 可能会产生线程安全问题的代码 }
4.lock接口:
lock() 加锁
unlock 解锁
private Lock lock = new ReentrantLock();
lock.lock();
需要加锁的代码
lock.unlock();
5.sleep()与wait()方法的区别
sleep是Thread类的静态方法,不需要对象所
wait方式是object类的方法,被所对象调动,只能出现在同步中
执行sleep()方法的线程不会释放同步锁
执行wait()方法的线程会释放同步锁,被唤醒后还需要获取锁才能执行
五:线程状态
NEW(
新建
)
|
线程刚被创建,但是并未启动。还没调用
start
方法。
|
Runnable(
可
运行
)
|
线程可以在
java
虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处
理器。
|
Blocked(
锁阻塞)
|
当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入
Blocked
状态;当
该线程持有锁时,该线程将变成
Runnable
状态。
|
Waiting(
无限 等待)
|
一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入
Waiting
状态。进入这个状态后是
不能自动唤醒的,必须等待另一个线程调用
notify
或者
notifyAll
方法才能够唤醒。
|
Timed
Waiting(
计时 等待)
|
同
waiting
状态,有几个方法有超时参数,调用他们将进入
Timed Waiting
状态。这一状态将一直保
持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有
Thread.sleep
、
Object.wait
。
|
Teminated(
被
终止
)
|
因为run
方法正常退出而死亡,或者因为没有捕获的异常终止了
run
方法而死亡。
|
线程状态图:
六:线程池Thread Pool
线程每次创建和销毁都会大量的消耗系统资源,线程池可以解决频繁创建线程的问题
1.线程池简单原理:
预先创建好一些线程,把他们放到一个容器中,需要线程执行任务的时候,从容器或在那个取出线程,任务执行完毕后将线程放回容器
2.jdk线程池
(1)Executors类
方法声明 | 方法含义 |
static ExecutorService newFixedThreadPool(int nThreads) | 创建一个可重复使用的固定线程数的线程池。链表存储 |
(2)ExeutrorService接口
线程池对象的管理接口,提交线程任务,关闭线程池等功能
方法声明 | 方法含义 |
---|---|
Future<?> submit | 提交线程执行的任务,返回null,因为run()方法没有返回值 |
Futuresubmit(Callable task) | 提交线程执行的任务,返回Future接口对象 |
void shutdown | 关闭线程池,但是要等所有线程都完成任务后再关闭 |
(3)Callable接口
类似Runnable接口,
方法声明 | 方法含义 |
call | 类似Runnable接口的run()方法,但有返回值 |