文字数:约1770字 阅读时间:40分钟
就是一个程序中有多个线程在同时执行
1. 进程
简单记进程指正在运行的程序,确切的来说,进程是处于运行过程中的程序,是系统进行资源分配和调度的基本单位,是操作系统结构的基础
2.线程
简单记是执行任务的一条通道
线程是进程中的一个执行单元,负责当前进程中程序的执行
3.线程与进程的关系
一个进程中可以包含多个线程,一个进程中至少应该有一个线程!
并发执行原理:CPU在多个线程之间进行高速切换;当CPU在执行线程1的时候,其他线程是出于阻塞状态的!
1.3.1 CPU在多个线程之间切换的方式
1按时调度(每个线程平均分配执行的时间)
2.抢占式调度(所有线程功能争抢CPU资源,谁抢到谁执行)java使用的就是这种方式
1.3.2 抢占式执行的特点
在任意时刻代码都有可能停下来,让别的线程执行(不受程序员控制的,仅取决于CPU本身)
1.提升用户的体验度
2.可以最大限度的发挥服务器的性能
是程序中的执行线程。是Java 给我们写好的一个表示线程的一个对象,创建一个thread对象就相当于创建一个一个新线程
Main方法实质上就是一个主线程,仅代表程序的入口,如果在Main线程中创建出其他线程并开启其他线程,那么开启的线程将独立占用自己的资源并执行;
Thread() :分配新的 Thread 对象,默认名字为thread-0、1、2、3
Thread(String name) :分配新的 Thread 对象,并使用name作为线程名称
Thread(Runnable target) :分配新的 Thread 对象。
Thread(Runnable target, String name) :分配新的 Thread 对象。
start() :使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
run():如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
Run方法实质上就是线程的任务方法,线程需要做的事情,都需要写在run方法之内,将由虚拟机自动调用run方法
sleep(long millis) : 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)(静态方法建议使用类名调用)
currentThread():获取当前线程对象,返回的是一个线程对象
getName():返回该线程的名称
setName(String name):改变线程名称,使之与参数 name 相同。
1 定义一个类继承Thread
2 重写run方法
3 创建子类对象,就是创建线程对象
4 调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法
1、定义类实现Runnable接口。
2、覆盖接口中的run方法。。
3、创建Thread类的对象(通过传入Runnable参数的构造方法)
4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
5、调用Thread类的start方法开启线程。
Runnable接口:可以简单理解为是一个任务接口,将线程需要执行的任务单独的提取出来形成了一个run方法
1.可以将线程类与任务类分开,(解耦合)方便分工合作
2.实现接口可以多实现,而继承只能单继承
方式1:创建线程匿名对象时,直接重写Thread类中的run方法
方式2:使用匿名内部类的方式实现Runnable接口,重写Runnable接口中的run方法
如果有多个线程同时运行,而这些线程可能会同时运行一个任务可能会出现BUG
5.1 产生BUG的原因
1.多线程是抢占式执行,任意时刻都有可能被别的线程抢走CPU的执行权(程序员无法控制)
2.多个线程使用了共享数据(只需要对共享数据进行控制即可)
5.2 线程安全解决方式
方式一:同步代码块
介绍:就是java提供的一种解决线程安全问题的方式
在代码块声明上 加上synchronized
synchronized (任意对象) {
可能会产生线程安全问题的代码
}
任意对象俗称锁对象;专业术语叫对象监视器
注意事项
1.需要保证多个线程使用同一个锁对象
2.同步代码块必须包裹在第一次使用共享数据的地方
方式二:同步方法
介绍:也是java提供的一种解决线程安全问题的方式
在方法声明上加上synchronized
public synchronized void method(){
可能会产生线程安全问题的代码
}
方式三:Lock接口
1. 介绍
也是java提供的一种解决线程安全问题的方式
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。
2. 对象创建方法
通过子类ReentrantLock创建对象
3. 常用方法
lock():获取锁(开始锁定代码)
unlock()释放锁(结束锁定,别的线程可以抢锁了)
4. 格式
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
5.3 同步方法与同步代码块的区别
1.同步方法便于分工合作
2.同步代码块可以指定对象监视器是谁,而同步方法不能指定对象监视器,默认使用this作为对象监视器
3.当同步方法是一个静态方法的时候,对象监视器是当前类的字节码文件对象(类名.class)
1.新建状态(new Thread())
2.运行状态(调用start)
3.死亡状态(结束运行)
4.阻塞状态(线程有执行的资格,但是没有CPU的资源),时刻准备进入运行状态
5.休眠状态(调用sleep方法),指定时间后醒过来
6.无限期等待状态(使用锁对象调用wait方法)