1.实现多线程
1.1进程和线程【理解】
进程:
是正在运行的程序
是系统进行资源分配和调用的独立单位
每一个进程都有它自己的内存空间和系统资源
线程:
是进程中的单个顺序控制流,是一条执行路径
单线程:
一个进程如果只有一条执行路径,则称为单线程程序
多线程:
一个进程如果有多条执行路径,则称为多线程程序
并行与并发
并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事。
多线程程序的优点:
1. 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
2. 提高计算机系统CPU的利用率
3. 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
1.2实现多线程方式一:继承Thread类【应用】
两个小问题
为什么要重写run()方法?
因为run()是用来封装被线程执行的代码
run()方法和start()方法的区别?
run():封装线程执行的代码,直接调用,相当于普通方法的调用
start():启动线程;然后由JVM调用此线程的run()方法
1.3设置和获取线程名称【应用】
1.4线程优先级【应用】
线程调度
两种调度方式
相同优先级:分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
不同优先级:抢占式调度模型:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些
Java使用的是抢占式调度模型
随机性
假如计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。
所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
java 中的线程优先级的范围是1~10,默认的优先级是5。10极最高。
1.5线程控制【应用】
static void yield():线程让步
暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程
若队列中没有同优先级的线程,忽略此方法
join() :当某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止
低优先级的线程也可以获得执行
static void sleep(long millis):(指定时间:毫秒)
令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。
抛出InterruptedException异常
stop(): 强制线程生命期结束,不推荐使用
boolean isAlive():返回boolean,判断线程是否还活着
1.6线程的生命周期【理解】
1.7实现多线程方式二:实现Runnable接口【应用】
实现步骤
1) 定义子类,实现Runnable接口。
2) 子类中重写Runnable接口中的run方法。
3) 通过Thread类含参构造器创建线程对象。
4) 将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
5) 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。
JDK1.5之前创建新执行线程有两种方法:
继承Thread类的方式
实现Runnable接口的方式
相比继承Thread类,实现Runnable接口的好处
避免了Java单继承的局限性
适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想
2. 同步
2.1 Synchronized的使用方法
Java对于多线程的安全问题提供了专业的解决方式:同步机制
1. 同步代码块:
synchronized (对象){
// 需要被同步的代码;
}
2. synchronized还可以放在方法声明中,表示整个方法为同步方法。
例如:
public synchronized void show (String name){
….
}
jdk.1.5 后增加实现线程的新方式
实现Callable接口
重要特点:
重写call方法;
该方法有返回值
可以抛出异常
实现的两个子接口
DocumentationTool.DocumentationTask
JavaCompiler.CompilationTask
实现线程的第四种:线程池
实现Executor接口
public interface ExecutorService extends Executor
一个Executor ,提供方法来管理终端和方法,
可以产生Future为跟踪一个或多个异步任务执行。
一个ExecutorService可以关闭,这将导致它拒绝新的任务。
提供了两种不同的方法来关闭ExecutorService 。
shutdown()方法将允许先前提交的任务在终止之前执行,
而shutdownNow()方法可以防止等待任务启动并尝试停止当前正在执行的任务。
一旦终止,执行者没有任务正在执行,没有任务正在等待执行,并且不能提交新的任务。
应关闭未使用的ExecutorService以允许资源的回收。
方法submit延伸的基方法Executor.execute(Runnable)通过创建并返回一个Future可用于取消执行和/或等待完成。
方法invokeAny和invokeAll执行invokeAll执行最常用的形式,执行任务集合,然后等待至少一个或全部完成。 (类别ExecutorCompletionService可用于编写这些方法的自定义变体。)
Executors类为此包中提供的执行程序服务提供了工厂方法。