多线程详解
核心概念
- 线程就是独立的执行路径;
- 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;
- main()称之为主线程,为系统的入口,用于执行整个程序;
- 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的。
- 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;线程会带来额外的开销,如cpu调度时间,并发控制开销。
- 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致。
线程创建的方法
-
Thread:继承Thread
-
Runnable: 实现Runnable接口
-
Callable: 实现Callable接口
线程调用为啥不是直接调用run() ,而是调用start()?
因为run方法会优先执行,没有并行的概念了,使用start方法可以开启一条新线程的同时执行主线程内容。
静态代理
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色
好处;
代理对象可以做很多真实对象做不了的事情
真实对象专注做自己的事情
Lambda表达式
为什么要使用lambda表达式
避免匿名内部类定义过多可以让你的代码看起来很简洁
去掉了一堆没有意义的代码,只留下核心的逻辑。
也许你会说,我看了Lambda表达式,不但不觉得简洁,反而觉得更乱,看不懂了。
那是因为我们还没有习惯,用的多了,看习惯了,就好了。
为啥要使用lambda
package test;
/*
推到lambda
*/
import static java.lang.System.*;
public class testlamda1 {
//3. 静态内部类
static class Like2 extends Like implements Ilike {
@Override
public void lambda() {
out.println("i like javaee");
}
public static void main(String[] args) {
Ilike like = new Like();
like.lambda();
like = new Like2();
like.lambda();
//4.局部内部类
class Like3 extends Like implements Ilike {
@Override
public void lambda() {
out.println("i like spring ");
}
}
like = new Like3();
like.lambda();
// 5。匿名内部类(没有类的名称,必须借助接口或父类)
like = new Ilike(){
@Override
public void lambda() {
out.println("i like maven");
}
};
like.lambda();
// 6. lambda简化
like = ()->{
out.println("i like javase ");
};
like.lambda();
}
}
//1. 定义一个函数式接口
interface Ilike {
void lambda();
}
// 2. 实现类
static class Like implements Ilike {
@Override
public void lambda() {
out.println("i like java");
}
}
}
使用lambda表达式
package test;
public class testlambda2 {
public static void main(String[] args) {
ILove love = (int a)->{
System.out.println("i love number"+a);
};
love.love(14);
}
}
interface ILove{
void love(int a);
}
//简化版
public class testlambda2 {
public static void main(String[] args) {
// 简化1
ILove love = null;
love = a -> {
System.out.println("i love "+a);
};
love.love(5);
// 简化2
love = a -> System.out.println("i love aa"+a);
love.love(520);
}
}
interface ILove{
void love(int a);
}
线程状态
线程停止
不推荐使用废弃的stop(),destroy()方法
推荐让线程自己停下来
建议使用一个标识位终止变量,当flag=false就终止线程的运行
线程休眠
sleep单位为毫秒
每个对象都有一把锁,sleep不会释放锁。
线程礼让
让当前执行的线程暂停,但不阻塞
让线程从运行状态转为就绪状态
让cpu重新调度,礼让不一定成功,看cpu调度。
Join
Join合并线程,待此线程执行完成后,再执行其他线程
观测线程状态
线程的优先级
优先级低只是意味着获得调度的概率低.并不是优先级低就不会被调用了.这都是看CPU的调度