多线程
程序内部的执行路径就叫线程,为了满足需求同时执行多个任务,就有了多线程
多线程有两种应用方式:
第一种是并发:在同一时刻,有多个指令在单个CPU上交替运行
第二种是并行:在同一时刻,有多个指令在多个CPU上交替运行
电脑的多线程可以通过CPU的来查询,逻辑处理器就是类似多线程表示的一种形式
多线程的优点:
- 提高应用程序的响应。可以增强用户体验。
- 提高计算机系CPU的利用率。
- 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
多线程的三种实现方式:
1:Thread
class Thread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("我在学习");
}
}
}
2:Runnable
class RunnableThread implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName()+":/t"+i);
}
}
3:Callable
class MyCallable implements Callable<Integer>{
//实现call方法,将此线程需要执行的操作声明在call()中
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
System.out.println(i);
sum+=i;
}
return sum;
}
}
需要注意的是第一种和第二种都不能有返回值,第三种可以有返回值
还有一种特殊的方式:
线程池
线程池
线程池可以提前创建好多个线程放入线程池中,使用时直接获取即可,使用后放回池中,可以避免频繁创建销毁、实现重复利用,提高效率
线程的生命周期
线程的安全性问题
为了解决线程的安全性问题,实现了两种方法:
第一种是同步代码块:
把需要进行操作共享的代码锁起来
第二种是同步方法:
对于同步代码块和同步方法有一个更加清晰的锁对象
锁
void lock()上锁
void unlock()释放锁
Lock接口不能实例化,这里采用它的实现类ReentrantLock来实例化
ReentrantLock的构造方法:
ReentrantLock():创建一个ReentrantLock的实例
注意:
还有一种死锁是需要我们避免发送的,
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了死锁。
出现死锁后,并不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续。
使用同步时应避免出现死锁。