Day11 多线程的学习,线程一些方法的使用

Day11

多线程的学习

线程休眠sleep的使用

sleep可以模拟网络延迟和倒计时。

模拟网络延迟

在线程中使用Thread.sleep()方法,能够放大问题的发生性,能更好的把握问题所在。

比如以前的例子,多个线程同时执行一个资源,会造成一个线程执行全部的结果导致无法看到本身线程的问题,使用sleep延迟后就能放大资源利用的情况,使问题暴露出来。

模拟倒计时

倒计时模拟也很简单,利用一个while循环和一个变量,在循环里面用Thread.sleep(1000)表示一秒过去,要模拟多少秒的倒计时。变量就设置多少,循环结束--自减即可。

同样Sleep方法也可以控制系统对时间的读取,一秒刷新一次等操作

每个对象都会有一把锁,sleep不会释放锁

线程礼让 yield

概念,线程礼让就是让当前执行的线程停止,不阻塞。

礼让不一定成功,意思是让正在执行的线程停止,回到重新竞争的局面。

测试了一下,有两个线程来跑,发现无论加不加礼让线程的方法,对结果的随机性都没什么影响,感觉用处不是很大

唯一的用处就是让正在执行的线程停止来和其他线程重新竞争CPU。

线程强制执行 join

join是比较强制的,能合并线程,等待该线程执行完后,再执行其他线程,这时其他线程会处于阻塞状态。

是需要有实例的线程的方法,运行后强制执行该线程。

此方法会让其他线程陷入阻塞,强制执行一个线程,如果该线程所花费的时间久,很造成资源堆积,很少用。

观测线程状态

如昨天学的线程的五大状态

新生 new后

就绪 Runnable

运行 running

阻塞 blocked

结束 dead

观测状态的方法 Thread.getState()

使用上述的方法就能观测到线程当前的状态。

如果线程已经启动过一次而且已经处于结束状态了,就不能够再启动该线程并且会报错。

线程的优先级

java有一个线程调度器,线程调度器通过优先级来决定调度哪个线程

线程优先级用数字表示1-10;

常用的方法 getPriority serPriority(int xxx) 来检测和设置线程的优先级。

main的默认优先级是5

先设置优先级再启动线程,优先级大的优先执行。

优先级低只是意味着获得的调度概率低,并不是优先级低的就不执行了,都全看CPU的调度。

守护线程

daemon 守护

线程分为用户线程和守护线程。

虚拟机必须确保用户线程执行完毕,不用等待守护线程执行完毕。

守护线程的用处 后台记录操作日志,监控垃圾,垃圾回收等待。

setDaemon()方法。默认是false,是用户线程,变为true就为守护线程 正常的线程都是用户线程

线程同步机制

发生在多个线程操纵同一个资源。即并发

线程同步就是一种等待机制,比如取票问题,一个人正在取票,另一个就不能取票,这样就会保证资源的安全。

需要访问对象的线程进入这个对象的等待池形成队列。

队列和锁

为了保证数据在方法中访问的正确性,加入锁机制synchronized

一个线程获得排他锁,独占资源,其他线程等待,这个锁其实可以设置在数据变动时,比如一个语句执行会是数据改变,就可以加入锁,当一个线程执行这个语句,其他线程就不能执行这个语句,当修改完后,其他线程才能修改。

但是也有问题

  • 一个线程持有锁,会导致其他需要此锁的线程挂起
  • 在多线程的竞争下,加锁,释放锁会导致比较多的上下文切换和调度延迟,引起性能问题。
  • 如果一个优先级高的线程等待优先级低的线程释放锁,会造成优先级倒置,引起性能问题

线程三大不安全的案例

买票案例

上面代码写过,一个资源被多个线程操纵时,可能出现剩一个票的情况,其他线程看到剩一个直接就拿了,相当于剩一个票被多个线程拿了,无中生有,肯定不正确也不安全。

银行取钱

可以在取钱机里也可以在网上取,在同时登陆后,由于还没开始取钱,两端的钱数一致,一端把钱取走后,另一端并不知道,依旧取钱,从而造成了不安全的情况。

list添加

由于多个线程同时在list添加,导致会把部分数据覆盖掉,从而造成的不安全。

思考

通过今天的学习,了解到线程一些方法的使用。都比较好理解,然后开始线程的不安全案例,这个我在刚开始线程的学习就遇到过,多个线程对一个资源进行操纵时,会产生一些不安全的情况,这时应该用同步方法来解决,就是用锁。这个方法能够保证数据的安全性,但是缺点也有就是会影响程序的性能。 锁关键字synchronized加上这个就完成了保护操作。

这里在学习操作系统也有了解到

posted @ 2022-09-25 22:06  青山隐隐丶  阅读(17)  评论(0编辑  收藏  举报