火车站中的每一个售票窗口可以看作一个个线程,我在窗口一买票,你可以在窗口二买票,你不需要等我,我也不需要等你,所以多线程并发可以提高效率。
四.思考
使用了多线程机制后,main方法结束,是不是有可能程序也不会结束
main方法结束之后只是主线程结束了,主栈空了,其他栈(线程)可能还在弹栈压栈。
五.对于单核的CPU来说,真的可以做到真正的多线程并发吗?
-
什么是真正的多线程并发
t1线程执行t1的,t2线程执行t2的,互不影响,这叫做真正的多线程并发, -
单核的CPU只有一个大脑,所以不能够做到真正的多线程并发,但是可以给到人一种“多线程并发”的感觉。
-
对于单核的CPU来说,在某一个时间点上实际上只能处理一件事情,但是由于CPU处理速度极快,多个线程之间频繁切换执行,给人的感觉是多个事情同时在做。
-
线程A:播放音乐
-
线程B:运行游戏线程A和线程频繁切换执行,人会感觉音乐一直在播放,游戏一直在打,给我们的感觉是同时并发的。
-
对于多核的CPU电脑来说,真正的多线程并发是没问题的。【4核CPU表示同一时间可以真正的有4个进程并发执行】
-
六. Java语言中实现线程的两种方式
- 第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法
MyThread myThread = new MyThread();
//启动线程
//start()方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成之后,瞬间就结束了
//这段代码的任务只是为了开辟一个新的栈空间,只要新的栈空间开出来,start()方法就结束了。线程就启动成功了。
//启动成功的线程会自动调用run方法,并且run方法在分支栈的底部(压栈)
//run方法在分支栈的地步,main方法在主栈的栈底部。run和main是平级的。
myThread.start();
//这里的代码还是运行在主线程中
for(int = i; i<1000;i++){
System.out.println("主线程---->"+i);
}
class MyThread extends Thread{
@override
public void run(){
//编写程序,这段程序运行在分支线程中(分支栈)
for(int i = 0;i<1000;i++){
System.out.println("分支线程---->"+i)
}
}
}
- run和start的区别
- 第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法
- 总结
第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承其他的类,更灵活 - 采用创建匿名内部类的方式可以吗?
七.线程图
八.关于线程的睡眠与终止
1.关于线程的sleep方法
static void sleep(long millis)
- 静态方法
- 参数是毫秒
- 作用是:让当前线程进入休眠,进入“阻塞状态”,放弃占有的CPU时间片,让给其他线程用
- Thread.sleep()可以做到这样的效果:间隔特定的时间,去执行一段特定的代码,每隔多久执行一次
- 关于sleep的一个面试题!!
2.终止线程的睡眠
注意:这个不是中断线程的执行,是终止线程的睡眠。
3.强行终止线程的执行
- t.stop() 【已过时,不建议使用】
- stop()方法缺点:会丢失数据,因为这种方式是直接将线程杀死,不建议使用
4.合理的终止一个线程的执行
九.(了解)关于线程的调度
1.常见的线程调度模型有哪些?
- 抢占式线程调度模型:哪个线程的优先级比较高,抢到的CPU时间片概率就高一点/多一点,java采用的就是抢占式调度模型。
- 均分式调度模型:平均分配CPU时间片每个线程占有的CPU时间片时间长度一样。平均分配,一切平等。有一些编程语言,线程调度模型采用的是这种方式。
2.java中提供了哪些方法是和线程调度有关系的呢?
- 实例方法:
void setPriority(int newPriority)//设置线程的优先级
int getPriority()//获取线程的优先级
最低优先级 1
默认优先级 5
最高优先级 10
优先级高的获取CPU时间片可能会多一些(但也不完全是,大概率是) - 静态方法
static void yield()//让位方法
暂停当前正在执行的线程对象,并执行其他线程
yield()方法不是阻塞方法,让当前线程让位,让给其他线程使用
yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”
注意:在回到就绪之后,有可能还会抢到 - 实例方法:void join()//合并线程
十.(重点!)关于多线程并发环境下,数据的安全问题
1.为什么是重点?
以后在开发中,我们的项目都是运行在服务器当中,而服务器已经将线程定义,线程对象的创建,线程的启动等都已经实现完了,这些代码我们都不需要编写
最重要的是:你要知道,你编写的程序要放到一个多线程下的环境下去运行,你更需要关注的是这些数据在多线程并发的环境写是否是安全的(重点!!!)
2.什么时候数据在多线程并发的环境下会存在安全问题呢?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!