Java并发编程—线程详解
创始人
2024-03-16 18:59:53

文章目录

  • 线程简介
    • 什么是线程
    • 多线程的使用
      • 什么时候需要使用多线程?
      • 写多少个线程比较合适?
    • 线程优先级
      • 靠谱的让出CPU的方法?
    • 线程的状态
      • 线程的状态有哪几种?
    • 线程的状态转换
    • Daemon线程
  • 启动和终止线程
      • 构造线程
      • 启动线程
      • 理解中断
      • 如何安全的终止线程
        • 直接调用interrupt会不会使线程中断?
  • 线程间通信
    • 等待/通知机制
  • 线程应用实例
    • 等待超时模式
    • CountDownLatch
        • countDownLatch代码

——————————————————————————————

线程简介

什么是线程

进程是由线程组成的
线程本质是一个栈

多线程的使用

什么时候需要使用多线程?

  1. 在cpu产生浪费时,需要性能提升的时候
  • cpu什么时候产生浪费比较严重?
    • 网络IO、磁盘IO的时候浪费比较严重
    • 网络IO:网络请求数据,在数据回来之前cpu一直在打空转
    • 磁盘IO:向磁盘发出调度,等数据回来也是cpu一直在打空转
  1. 需要同时运行多个线程

写多少个线程比较合适?

一般是二十四十个线程比较合适(回答的时候答2040之间的具体一个数),一方面因为CPU有上下文切换,消耗时间;另一方面读写数据库单批次数据不能太大,太大会影响数据库的性能

线程优先级

下面代码,设置5个高优先级,5个低优先级,让10个线程处于就绪态,一起竞争资源,谁的count越大,谁竞争到的次数越多(优先级高的,竞争到的次数应该高)。
但是结果是,高优先级和低优先级count结果一样,说明设置的优先级没用

public class Priority {private static volatile boolean notStart = true;//为true,在29行的循环才能执行private static volatile boolean notEnd = true;//为true,在35行的循环才能执行public static void main(String[] args) throws Exception {List jobs = new ArrayList();for (int i = 0; i < 10; i++) {int priority = i < 5 Thread.MIN_PRIORITY : Thread.MAX_PRIORITY;Job job = new Job(priority);jobs.add(job);Thread thread = new Thread(job, "Thread:" + i);thread.setPriority(priority);thread.start();}notStart = false;//10个线程进入就绪态之后,notStart变为true,每个线程进入就绪态后都会进入第二个循环执行++操作TimeUnit.SECONDS.sleep(10);//10个线程竞争了10秒钟,在这之前会让jobCount++notEnd = false;for (Job job : jobs) {System.out.println("Job Priority : " + job.priority + ",Count : " + job.jobCount);}}static class Job implements Runnable {private int priority;//私有的,int类型的优先级private long jobCount;//工作次数public Job(int priority) {//指定这一次运行的优先级this.priority = priority;}public void run() {while (notStart) {//如果notStart为true,一直执行这个循环//先进入就绪态的线程,先执行的概率比较大hread.yield();//保证了公平//因为进入了运行状态但是没真正执行++操作,只是打空转后让出cpu//让出后重新进入就绪态,是操作系统记录位置,不是程序计数器}while (notEnd) {Thread.yield();//这句话是让出cpu的意思//为什么要加上这个(因为这个方法不靠谱,并不能立刻让出cpu,cpu会执行一段之间)//这个让出cpu后,会执行下面的++操作jobCount++;}}}
}

在这里插入图片描述
count数字这么大,也表示Thread.yield();方法不靠谱,并不是执行一次++操作就让出cpu,可能执行了1000次或10000次才让出cpu。

靠谱的让出CPU的方法?

sleep(0)或sleep(1):可以立刻让出cpu

线程的状态

线程的状态有哪几种?

**线程状态:**新建状态,就绪状态,运行状态,阻塞状态,等待状态,终止状态(死亡状态)。

  • 新建状态:线程被构建,但是还没有调用start()方法
  • 就绪状态:调用了start()方法,还没开始运行
  • 运行状态:开始运行后,的运行时期
  • 阻塞状态:(是加锁竞争失败的)当几个线程同时竞争资源,竞争失败的线程全部进入阻塞状态,当竞争成功的线程释放锁的时候,会通知进入阻塞状态的线程,他们才会重新进入运行状态竞争资源。(如果是轻量级锁会自旋,能主动能够知道资源被释放了,而重量级锁无法知道资源什么时候释放,需要有人通知他)
  • 等待状态:调用 wait() 或sleep()方法,调用 wait()需要事先加锁
  • 终止状态(死亡状态):线程执行结束,被回收
    在这里插入图片描述

线程的状态转换

在这里插入图片描述

Daemon线程

  • 是一种守护线程,Daemon线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。
  • 做辅助性的线程
  • Daemon属性需要在启动线程之前设置,不能在启动线程之后设置

启动和终止线程

通过调用线程的start()方法进行启动,随着run()方法的执行完毕,线
程也随之终止

构造线程

在运行线程之前首先要构造一个线程对象,线程对象在构造的时候需要提供线程所需要
的属性
==》如线程所属的线程组、线程优先级、是否是Daemon线程等信息(设置线程的父线程等)
==》可以通过构造方法加属性,也能通过其他方法加属性。

启动线程

调用start()方法就可以启动这个线程。

  • 启动一个线程前,最好为这个线程设置线程名称,因为这样在使用jstack分析程
    序或者进行问题排查时,就会给开发人员提供一些提示,自定义的线程最好能够起个名字。

理解中断

中断好比其他线程对该线程打了个招呼,其他线程通过调用该线程的interrupt()
方法对其进行中断操作。
如何安全的终止线程

如何安全的终止线程

直接调用interrupt会不会使线程中断?

其他线程想让线程中断,需要在该线程中写代码配合, 如果只单纯的有其他线程调用该线程的中断方法,是不起任何作用的。
线程内需要配合,才能使这个线程中断
在这里插入图片描述
线程通过方法isInterrupted()来进行判断是否
被中断,也可以调用静态方法Thread.interrupted()对当前线程的中断标识位进行复位。

线程间通信

等待/通知机制

一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个
过程开始于一个线程,而最终执行又是另一个线程。
简单的办法是让消费者线程不断地循环检查变量是否符合预期。
在这里插入图片描述
上面这段伪代码在条件不满足时就睡眠一段时间,这样做的目的是防止过快的“无效”尝
试。
1)难以确保及时性。
2)难以降低开销。
在这里插入图片描述
示例:
WaitThread和NotifyThread,前者检查flag值是否为false,如果符合要求,进行后续操作,否则在lock上等待,后者在睡眠了一段时间后对lock进行通知。
(等待状态不会进入竞争,阻塞状态会被唤醒后参与竞争)
在这里插入图片描述

线程应用实例

等待超时模式

前面的章节介绍了等待/通知的经典范式,即加锁、条件循环和处理逻辑3个步骤,而这种
范式无法做到超时等待
假设超时时间段是T,那么可以推断出在当前时间now+T之后就会超时。
定义如下变量:

  • 等待持续时间:REMAINING=T。
  • 超时时间:FUTURE=now+T。
    这时仅需要wait(REMAINING)即可,在wait(REMAINING)返回之后会将执行:
    REMAINING=FUTURE–now。如果REMAINING小于等于0,表示已经超时,直接退出,否则将
    继续执行wait(REMAINING)。
    在这里插入图片描述

CountDownLatch

CountDownLatch属于线程同步的一种,让线程同时执行
CountDownLatch功能:
使用了CountDownLatch来确保ConnectionRunnerThread能够同时开始执行,并
且在全部结束之后,才使main线程从等待状态中返回。

countDownLatch代码

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...