01-多线程概述
05-1线程的实现方式
线程是依赖进程的,进程是需要系统资源的,以为Java
不能直接嗲用系统的API,但是JAVA
可以调用C/C++
封装好的方法去调用系统资源,这个类就是Thread
多线程并行:多个任务同时运行,需要多核CPU
并发:是指两个任务通请求运行,而处理器只能接受一个任务,就把这两个任务安排轮流进行,由于时间间隔比较短,使人感觉两个任务都在运行
cpu:对数据进行计算,指挥电脑中软件和硬件干活
线程:
线程调度:
* 分时调度:所有的线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间
* 抢占式调度:优先让优先级搞的线程使用CPU,如果线程的优先级相同,那么会随机的选择一个,Java使用抢占式调度
如何实现多线程:
* 方式一: 1. 继承Thread
类,并重写run()
方法 2. 将要执行的代码放入run
方法中 3. 新建这个类,并调用start
方法开启线程(java虚拟机会调用run方法中内容,必须调用start方法才会启动新的线程,对象.run方式调用,在工作线程运行)
* 方式二: 1. 新建类实现Runnable
方法,将代码写入方法中 2. new Thread(Runnable对象).start()
; (使用多态将内容传递进去) 最终都是调用的start方法->start0->JVM(通过vmSysBOlHandles)调用
* 理解:run方法中相当于任务,也就是说此方法会在线程的执行空间中运行;Thread相当于工人,将Runnable(任务)交给工人;start方法,开始执行
05-2 线程安全问题
原因:多线程操作共享数据
05-2-1线程同步方式
- 同步代码块
- 同步方法
- Lock锁机制
05-2.1线程同步问题操作
-
同步代码块
格式
synchronized(锁对象){
需要同步的代码
}
同步锁:
1. 代码块中的锁对象可以是任意对象
2. 但是必须保证多个线程使用的锁对象是同一个
* 锁对象作用:只让一个线程在同步代码块中执行
图注释:创建的锁对象,必须在run方法的外部,使得唯一,如果在run方法内部,那么各个线程执行run方法的时候,都会创建将要使用的锁对象,锁都一不一样,没用。原理,是到了同步方法,会检查是否有锁,有的话,就拿锁进去,直到执行完才归还。当另外线程执行到同步方法,检查,没有锁,阻塞。
-
同步方法
格式
public synchroniczed void method{
可能会产生线程安全问题的代码
}
同步方法会把方法内部的代码锁住,只让一个线程执行
同步方法的锁对象:
也就是实现类对象(new RunnableImpl()
),也就是this
(代表当前对象)
静态代码块对象:本类的class对象-->class文件对象(类名.class)
-
Lock锁
Lock
接口中方法,实现比Synchronized
方法和语句可获得更广泛的锁的操作
Lock
接口的方法;
void lock
获取锁
void unLock
释放锁
ReentrantLock implements Lock
接口
使用步骤:- 在成员位置创建一个
ReentrantLock
对象 - 在可能出现安全问题的代码前调用Lock接口中的方法lock获取锁
- 在可能出现安全问题的代码后调用Lock接口中的方法unlock释放锁
- 在成员位置创建一个
l.lock();
线程安全的代码
finally{
//无论程序是够异常,都把锁释放
l.unLock();
}