2021-05-18

JAVA多线程基础

  1. 了解进程和线程
  1. 了解进程和线程:现在的操作系统都是在支持进程,每一个任务通常都对应的一个进程,当一个程序进入内存的时候,它就会变成一个进程。进程 > 可以对应为一个程序;线程 >一个程序中处理的不同任务;主线程 > 关联着进程的生命周期。进程是处于运行过程中的程序,具有一定的独立功能。进程是系统进行资源分配和调度的一个独立单位,具有三种特征。
  1. 独立性:进程是系统中独立存在的实体,拥有自己独立的资源,每一个进程都拥有自己私有的地址空间;在没有通过进程本身允许的情况下,一般一个程序的进程是不可以访问其他进程的地址空间。
  2. 动态性:进程和程序来说,程序只是停留在硬盘上的一些文件,也就是程序只是一个静态的指令集合,而进程就是一个真正活动的一个集合,当一个程序读取获取进入程序之后,就有了一个时间的概念,从而变成了一个进程。
  3. 并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会互相影响。

 

  1. 多线程是对多进程的一个扩展,使得同一个进程可以同时并发处理多个任务,也就是一个进程下执行着多个任务;线程(Thread)被称为轻量级的进程,线程是进程执行的单元,就像进程在系统中那样,进程是由线程构成的;线程在程序中是独立并发的执行的,当进程被初始化之后,主线程也就被创建了;绝大多数程序来说,很多程序就只有一个主线程,也可以在内存中创建很多的线程的分支。
  2. 线程是进程的组成部分,一个进程拥有多个线程,一个线程必须有一个父进程,也就是线程是不能单独存在的必须依付于进程而存在,而进程又有一个主线程来支撑,进程和线程是一个相互依赖的关系;可以共享一下父进程的一些资源(共享变量)和以及环境的东西;子线程之间可以共享父进程的一些资源。

简单的说:

  • 进程:进程是系统进行资源分配和调度的基本单位,可以理解为一个正在执行的程序。
  • 线程:线程是程序执行的最小单位,一个进程可以有一个或者多个线程构成。

总结:操作系统可以执行多个任务,每一个任务就是进程,进程可以同时执行多个任务,每一个任务就是线程。

 

  1. JAVA线程的实现
  1. JAVA语言主要提供了两种实现线程的方式:
  • 继承Thread(线程)类创建线程类 > 主函数就是主线程的入口
  • 实现Runnaable接口创建线程类

 

  1. 线程类的方法
  1. 继承Thread类创建线程类

实验步骤:首先,在主函数外面先创建一个类继承线程(Thread),然后重写run方法,输出需要实现的任务,通过for循环把要实现的任务实现出来,然后回到主函数创建线程的对象,把需要实现子线程的功能放入启动子线程的代码块中,注意启动一个线程,调用的是start的方法。

 

  1. 实现Runnable接口创建线程类

实验步骤: 首先,在主函数外面定义一个类直接实现Runnaable的接口,然后重写run方法,输出需要实现的任务,在Runnaable中getName是线程的那个类的方法,我们是直接实现Runnaable的接口的,没有继承那个类,所以不能直接使用getName),但是如果要打印线程的名称,直接使用线程这个类点当前线程(安全线程)再获取名字(getName) >(Thread).currrentThread().getName,就可以通过for循环把要实现的任务实现出来 ,然后回到主函数使用线程的类(Thread),把Runnaable的一个实现类作为一个参数传输进来,也就是new一个Runnaable的实现类,把实现子线程的功能放入启动子线程的代码块中,注意启动一个线程,调用的是start的方法。

 

  1. JAVA线程类的常用基本方法

 

  1. Thread(Runnable target, String name):线程的名称
  2. currentThread():获取当前线程的对象
  3. sleep(long millis):线程休眠多次的时间
  4. yield() :暂停现在执行的程序
  5. start():启动一个线程,虚拟机会调用run方法
  6. getId():获取线程的标识符
  7. getName() :获取线程的名称
  8. getPriority() :获取线程的优先级 > 线程的优先级默认是5
  9. isAlive():线程是否处于活动状态。
  10. join() :等待该线程终止。
  11. setName(String name) :设置线程的名称
  12. setPriority(int newPriority):更改线程的优先级。参数范围[1,10]

 

  1. JAVA线程状态也就是线程的生命周期    

 

 

线程的五种状态:

  • 新建状态(New):线程实例化之后new出来之后,它就处于现在的这个状态。
  • 就绪状态(Runnable):线程已经实例化了,并且调用start()方法,虚拟机启动该线程,该线程会以一个就绪状态随时可能会被调度执行。
  • 运行状态(Running):如果想要运行的话,线程需要得到处理资源(比如CPU的运算资源),只要线程得到处理资源就可以从就绪状态进入到运行状态。

进入运行状态有三种选择:

  1. 调用yield()>暂停的方法,停止运行或者程序失去了处理资源就会回到就绪状态
  2. 调用sleep()休眠的方法/IO阻塞或者等待同步锁或者等待通知就会进入阻塞状态
  3. 从阻塞状态等到了sleep()结束/IO已经有了返回或者等待拿到同步锁又或者拿到了通知,就会阻塞状态从新进入一个就绪状态,再一次等待系统分配资源。

 

  • 阻塞状态(Blocked):线程因为某个原因暂停执行,并让CPU的使用权后便进入了阻塞状态。
  1. 等待阻塞:程序运行了wait()方法之后,线程就会被放入等待池。
  2. 同步阻塞:运行线程获取对象的同步锁时,该锁已经被其他线程获得,虚拟机会把该线程放入锁定池。
  3. 其他线程:调用运行线程的sleep()方法或者join()方法或者IO请求的时候,进入阻塞状态。
  • 结束状态(Dead):当一个程序执行调用的是stop()/Eroor或者抛Exception在或者执行完毕之后的情况下,它就代表完成了线程工作就进入了死亡状态也就是程序已经结束了。

 

  1.  线程同步(线程的安全)

通过模拟取钱过程演示线程安全问题。 一般取钱过程:-》(施显君授课)2021-3-29

  1. 用户输入账户、密码,系统判断用户的账户、密码是否匹配。
  2. 用户输入取款金额。
  3. 系统判断账户余额是否大于取款金额。

4. 如果余额大于取款金额,则取款成功;如果余额小于取款金额,则取款失败。

在模拟过程中就模拟后面三步,没有模拟账户密码验证过程。

 

  1. 使用同步代码块 
  • 为了解决线程的安全问题,JAVA的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块。

 

obj叫作同步监视器一般叫做锁对象,在任何线程进入代码块之前必须先获得锁对象(obj);锁对象是可以任意对象,但必须保证是同一对象。

任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后该线程会释放对该同步监视器的锁定。

 

  1. 同步方法:直接加载在方法上面;非sattic方法,无需显示指定同步的监视器,同步方法的同步监视器就是 > this,也就是调用方法的对象。

 

  1. 同步锁(Lock)
  • Java5开始,提供了一种更强大的线程同步机制,更广泛的锁定操作,比较常用的是ReentranLock(可重入锁)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值