多线程
并发与并行
并发:
- 指两个或多个事件在同一个时间段内发生
并行
- 指两个或多个事件在统一个时刻发生
线程与进程
线程:
- 进程中的执行单元、负责当前进程中程序的执行,一个进程至少有一个线程。
进程:
- 一个进入内存的(运行)的程序,一个应用程序可以有多个进程(完成多个不同的功能)比如qq可以同时登录多个账号。
线程调度
分时调度
- 所有线程轮流使用cpu,平均分配每个线程的cpu使用时间
抢占式调度
- 优先级高优先调用cpu
线程创建
第一种方法
1.创建java.lang.Thread子类
2.重写run方法
3.创建子类对象
4.调用子类对象start()方法
注意:如果是调用run方法,则只是把run()方法加入到Main线程中执行,而不是在新开辟的线程中执行,调用start()会创建新的栈空间运行新线程
第二种方法
使用匿名内部类创建(Runnable())
Thread t=new Thread(new Runnable(){
@override
public void run(){
}
})
Thread的常用方法
获取线程名称
- public String getName() 获取线程名称
- public static String currentThread() 获取正在运行的线程
设置线程名称(两种方法)
- public void setName()
- 创建带参数的构造方法,传递参数到父类的构造方法
控制线程
- public void sleep(long mills) 使线程休眠
- public void notify() 激活线程
Thread 和Runnable 的区别
Runnbale
- 避免了单继承
- 程序解耦,实现run定于与start调用分开
线程安全
不同线程对同一资源的同时访问会出现安全问题
线程同步
同步代码块
格式
锁对象需要是相同的
synchronize(锁对象){
同步的代码块
}
锁对象相当于钥匙,同步的代码块相当于房子,线程先判断是否持有锁对象,当线程持有锁对象的时候可以运行同步代码块的代码,没有锁对象会进入阻塞对象,直到拥有锁对象的线程将锁对象归还。
同步方法
定义方法
-
public syschronize void method(){};
同步方法的锁对象为实现类对象(即实现了runnable接口的类对象)
静态同步方法
public static syschronize void method(){}
锁对象:本类的class对象
Lock 锁
java.util.concurrent.locks (jdk1.5)
方法
-
void lock()
-
void unlock()
lock的实现类
Reentrantlock
-
在成员位置创建对象
-
在可能出现安全问题的地方调用该方法获取锁
-
在同步代码结束处调用unlock
Lock l=new Reentrantlock();
l.lock();//在可能出现安全问题的地方调用该方法获取锁
l.unlock();//在代码结束处调用
线程的状态
此图片来源黑马java教学视频
6种状态
新建状态
运行状态
阻塞状态(与其他线程争夺锁对象,争夺失败进入该状态)
休眠状态
无限休眠状态(调用了wait()方法,不传参)
死亡状态
线程的等待与唤醒
wait()与notify()的转化
使用锁对象调用以上的两个方法,实现线程的等待与唤醒,锁对象需要唯一
notifyall() 唤醒所有的线程
同上
线程池的代码实现
java.util.cocurrent.Excutors 用于产生线程池
方法
-
static ExecutorService newFixedThreadPool(int Threads) 创建线程池
返回ExecutorService 接口的实现类
java.util.cocurrent.ExcutorService 线程池操作对象
接口的方法
-
void submit(Runnable ) 提交一个Runnable
-
void shutdown 毁线程池对象
使用步骤
- 创建线程池
- 创建一个Runnable的实现类,重写run方法,设置线程任务
- 调用submit方法,传递Runnable
- 调用shutDowm方法,销毁线程池对象