一、进程
1、进程:
操作系统(os)中正在执行的应用程序(软件)一个操作系统中允许多个进程同时工作,被称为多进程
2、多个进程并发执行原理:
宏观上:并行,多个进程一起执行
微观上:串行,一个一个的线程执行,一个cpu时间片是能给一个进程,只有一个进程工作,哪一个进程获取当前cpu时间片哪一个进程执行对应的任务。
二、线程
1、线程:
在进程中执行的任务,一个进程中同时可以执行多个线程任务(多个线程),每个任务称为一个线程,线程是进程的执行单元,线程也被称为轻量级的进程
2、目前程序为单线程:
以main函数的开始为开始,以main函数的结束为结束,这个线程被称为主线程(利用Java语言实现多线程)
3、线程的组成部分
(1) cpu:获取cpu时间片的线程才能执行对应的任务代码 (多个线程并发:宏观上并行,微观上串行)
(2) 数据:栈空间独立,堆空间共享(每个线程都有独立的栈空间,所有的线程共享同一个堆空间)
(3) 代码:利用Java代码实现多线程
三、代码实现多线程
1、第一种方式:
(1) 定义一个类继承java.lang.Thread类,覆盖run方法 注意:将线程任务定义在run方法
(2) 创建线程对象: MyThread t1 = new MyThread();
(3) 开启线程:调用start方法
t1.start();//jvm默认调用run方法
2、第二种方式:
(1) 定义一个类实现 java.lang.Runnable接口,同时实现 run方法(将线程任务定义在run方法)
(2) 创建任务对象:Mytarget tg = new MyTarget();
(3) 创建线程对象,并将任务传递给线程对象
Thread t2 = new Thread(tg);
(4) 开启线程:
t2.start(); // jvm默认执行run方法
四、线程的状态
1、基本状态
(1) 在给定的时间点上,一个线程只能处于一种状态
(2) 在API中,将Ready和Running统称为 Runnable状态
2、线程的等待状态
(1) static void sleep(long ms):
让当前线程处于休眠状态(有限期的等待状态),单位为毫秒,利用Thread.sleep(100);操作即可;处
于有限期等待状态的线程释放cpu资源
代码展示
结果展示:主线程main 和 t1线程 交替抢占时间片
(2) void join():
Thread类中的成员方法,允许其他线程加入当前线程的执行任务中,在主线程中调用 t2.join();此
时代表主线程让步于 t2线程,主线程进入无限期的等待状态,等待t2线程执行完毕的标记,主线程
才继续往下执行
代码展示:
结果展示: t2 先执行 , 执行结束后主线程 main 执行
线程状态补充
五、线程同步
1、临界资源:
多线程并发访问时,被多个线程共享的同一个对象
2、原子操作:
不可分割的多步操作,被视为一个整体,其执行的顺序和步骤不能被打破
3、线程同步:
多线程并发访问时,保证原子操作不被破坏的一种技术手段,利用线程同步保证原子操作不被破
坏,从而保证临界资源的正确性
4、线程同步的实现方式:同步代码块
(1) 同步代码块对临界资源对象加锁
(2) 语法:
synchronized(临界资源对象){
// 原子操作
}
(3) 位置:定义在方法内部
5、线程同步实现方式二:同步方法
(1) 同步方法:被synchronized修饰的方法称为同步方法
(2) 语法:
访问修饰符 synchronized 返回值类型 方法名(参数){
// 原子操作
}
代码展示:
结果展示
6、线程同步执行的原理:
线程执行过程中,遇到同步代码块,只有获取临界资源对象的锁标记才能执行同步代码块{}中的代码,并且将{}中所有的程序全部执行完,才能释放拥有的锁标记;如果一个线程试图获取锁标记时,此锁标记被其他线程占用,则当前线程进入阻塞状态(Blocked,等锁标记),只有获取等待对象锁标记并获取cpu时间片才能执行同步代码块{}中内容。
注意:同步方法等价于同步代码块
public synchronized void method(){
// 原子操作
}
等价于:
public void method(){
synchronized(this){
// 原子操作
}
}
7、ArrayList 和 Vector区别?
ArryList:线程不安全,底层方法为非同步方法,并发效率高
Vector:线程安全,底层方法为同步方法,并发效率低
注意:如果想实现线程同步,需要不同的线程抢占的同一个对象锁标记(对临界资源加锁)才能达到互斥目的,从而实现线程同步,数据安全。