1、需求:要下载两个文件,文件A和文件B要同时下载!如何实现???
2,进程:正在运行的一个程序就是进程。
3,线程:程序中独立的执行路径。
4,进程和线程的案例
公路:进程
车道:线程
5,进程和线程的作用
进程:用来封装线程并为线程分配资源。
线程:用来执行代码。
6,线程的分类
单线程:程序中只有一条执行路径,同一时间只能干一件事情。
多线程:程序中有多条执行路径,同一时间可以干多件事情。
7,开启线程之继承Thread类
8,主线程和子线程
1) 什么是主线程
在程序启动时由JVM自动创建并执行main的线程。
执行路径:从main方法开始直到main执行完毕。
2) 什么子线程
除了主线程以为的所有线程就子线程。
执行路径:从run方法开始直到run方法执行完毕。
9,线程的运行模式
线程是由CPU负责执行。
1) 分时式模式
每一个线程平均分配CPU的使用时间。每一个线程分配的时间是相同。
2) 抢占式模式
优先级高的线程优先使用CPU,如果优先级相同,则多个线程一起争夺CPU使用权。Java程序多线程属于抢占式模式。
10,多线程运行的特点和内存分析
1) 运行特点:随机性
2) 内存分析
11,多线程的优点(好处)
1) 提高了CPU的使用率。
2) 提高了程序的执行效率。
11,线程常用方法
线程常用方法
* String getName() 获得线程名称。默认命名:Thread-序号,从零开始。
* void setName(String name) 设置线程名称
* static void sleep(long millis)
* 让当前方法执行所在的线程休眠指定的毫秒时间
* 单位:毫秒
* static Thread currentThread()
* 获得当前方法执行所在的线程对象。
12,线程的状态
1) 新建状态
2) 就绪状态
3) 运行状态
4) 阻塞状态
5) 死亡状态
13,线程安全
什么是线程安全
多个线程同时操作一个共享资源时仍然能得到正确的结果,则称为线程安全。
15,同步代码块解决线程安全问题
1) 同步代码块的格式
synchronized (锁对象) {
共享资源的代码
}
1) 同步代码块的原理
能够保证同一时间只能有一个线程执行代码块中的代码。
2) 同步代码块的注意事项
1) 锁对象可以是任意对象。
2) 锁对象必须是所有线程共享的对象。
// 定义变量记录总票数
public static int tickets = 100;
// 锁对象
private static Object lockObj = new Object();
public Tickets(String name) {
super(name);
}
@Override
public void run() {
// 开始卖票
while(true) {
// 美女B
synchronized (lockObj) {
// 判断是否还有剩余票数
if(tickets > 0) {
try {
// 休眠下
// 美女A
Thread.sleep(10);
// 卖一张票
System.out.println(getName() + " 卖了一张票,还剩 " + (--tickets) + " 张票");
continue;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("票没了!!!");
14,同步方法解决线程安全问题
1) 同步方法的格式
修饰符 synchronized 返回值类型 方法名(参数列表) {}
2) 同步方法的原理
能够保证同一时间只有一个线程调用方法。
3) 同步方法的锁对象
如果是非静态同步方法,锁对象是:this
如果是静态同步方法,锁对象是:类名.class
4) 同步方法的使用
15,Lock接口
JDK1.5新特性。
1,常用方法
1) void lock():获取锁
2) void unlock():释放锁
2,注意事项
1) 获取锁和释放锁的代码必须成对出现。
16,线程的实现方式
1,实现Runnable接口
1) 实现步骤
- 创建一个类实现Runnable接口,重写run方法。
- 创建Runnable实现类对象
- 根据Thread类对象传递Runnable实现类对象。
- 调用start方法开启线程。
-
1) 实现Runnable接口的好处
- 避免了Java类单继承的局限性。
- 可以方便多个线程之间共享数据。
- 线程与任务分离,降低了程序的耦合性。
- 17,线程池技术
-
1) 什么是线程池
- 一个用来创建和管理线程对象的容器。
2) 为什么要使用线程池
- 因为创建线程和销毁线程需要消耗大量的CPU资源,如果频繁创建线程和销毁线程会导致效率低,资源浪费。
3) 线程池的核心思想
- 线程复用。避免频繁创建线程和销毁线程带来开销。
-
1) 线程池使用方式
- 提交Runnable任务
- 提示Callable任务
-
1) 线程池常用方法
void shutdown()
销毁线程池对象,会等待线程池中的任务执行完毕才销毁
void shutdownNow();
销毁线程池对象,立即销毁线程池,不管线程池中的任务是否执行完毕。
Future submit(Runnable task)
提交runnable任务
2) 使用线程池的步骤
- 通过工厂类Executors创建线程池对象并指定线程数量。
- 调用submit方法提交任务给线程池
- 调用shutdown方法销毁线程池。