二十一章 – 多线程
一、理解线程的概念
进程: 一个程序的运行实例,正在进行的程序。通常来说一个程序对应着一个进程。它有独立的内存和系统资源
线程: 是CPU中运算和分派的基本单位,也是进程中运算的基本单位,一个进程中可以有多个线程,一个线程可以独立完成一个顺序控制流程
多线程和单线程概念:
单线程: 如果一个程序中只有一个线程,则称为单线程
多线程: 多个线程
多线程和单线程区别:
1.多线程在执行时并不一定有单线程执行快
2.多线程产生的根本原因也是因为它的最根本的有事在于我们能够在一个程序中同时干多件事,可以充分利用CPU资源
3.多线程有两个概念:一种是指,单核CPU的多线程,一种是多核CPU的多线程。
单核CPU:同时只能执行一个线程,但是同样可以实现多线程,这个多线程恒是抢占式/交替执行
多核CPU:可以进行交替执行,也可以实现真正的物理上的并行执行时
主线程
一个进程有且仅有一个主线程,主线程负责程序的开启和最后关闭动作的线程
java.lang.Thread类
二、 掌握线程的基本创建和启动
1.继承java.lang.Thread类
1.继承Thread类
2.重写run()方法
3.调用start()启动线程
2.实现java.lang.Runnable接口
1.实现java.lang.Runnable接口
2.重写run()方法
3.创建线程对象 组装runnable接口的实现类 调用start()方法启动线程
分别特点:
继承Thread类: 编写简单可时直接操作线程,适用于单继承
实现Runnable接口: 避免单继承的局限性,便于共享资源
定义线程-创建线程对象-启动线程-终止线程
线程start()和run()的区别:
如果是调用run()方法,他只是一个普通方法,届时将只有主线程在执行此方法而已(和以前的其他方法调用一样)
如果调用该start()方法,它会开启一个线程,然后此线程将会和其他县城交替执行某些任务,此线程执行的内容
三、理解现成的几种状态
创建状态: 当new Thread()时,线程处于创建状态
就绪状态: 当调用start()之后 线程处于就绪状态
运行状态: 当线程被分配到CPU资源,线程处于运行状态,如果线程运行状态时,是出于抢占式执行的,当没抢到时又回到就绪状态
死亡状态: 当线程执行完任务,或者被外部干涉结束苏,线程会进入死亡状态
堵塞状态: 当用户在输入/线程在休眠时,线程会进入阻塞状态,党组色状态结束后惠及进入就绪状态
四、掌握线程调度的常用方
法线程优先级 :
Thread.MAX_PRIORTY(最大)
Thread.MIN_PRIORTY(最小)
线程休眠:
public static void sleep(毫秒)
Thread.sleep(毫秒)
线程礼让:
public static void yield()只提供一种可能 不能保证一定会实现礼让
线程强制执行:
void join(毫秒/+纳秒)
五、掌握线程的同步问题(线程安全)
同时有多个线程在执行任务 ,虽然在交替执行但是由于速度快 ,如果有些资源被共享可能导致资源出错
并发
可以通过加锁的方式来解决安全问题
synchtonized同步
1.同步方法
public synchtonized void ticket(){
}
2.同步代码块
synchtonized(this){
}
六、常见的线程安全类型
HashMap 和 Hashtable区别
Hashtable 和 HashMap 都实现了Map接口
ht线程安全但是效率低
hm线程不安全但是效率高
ht键值都不能为null;
hm键值都可以为null;
ht继承Dictionary
hm继承AbstractMap
** StringBuffer 和 StringBuilder**
他们在使用中没有区别,
但是StringBuffer是线程安全的
StringBuilder非线程安全,效率高
ArrayList和Vector
Vector是线程安全的
ArrayList是非线程安全的