线程基础总结

ofeqx.com 方程式科技共享平台 外文资料好找好用。大数据有序化,
专业垂直领域体系的知识共享盘平台,发表您的创作与我们共产知识。
在这里插入图片描述

新建 就绪 运行 等待 阻塞 消亡
多线程是异步的,所以千万不要把eclipse 里的代码的顺序当成线程执行的顺序,线程被调用的时机是随机的。
实现线程的方式 一种是继承thread 类 另一种是实现runnable 接口
thread 不支持多继承 为了支持多继承可以实现runnable 方法
start()通知线程规划器此线程已经准备就绪,等待调用线程对象的run()方法 这个过程其实就是让系统安排一个时间来调用thread 的run()方法 也就是使先线程得到运行,启动线程具有异步执行的效果。
如果调用代码thread.run()就不是异步执行 而是同步 线程不交给 线程规划器 而是有main主线程来调用 run()也就是必须等run()方法中的代码执行完后才可以执行后边的代码。
线程的启动顺序与start()执行顺序无关
thread的构造函数可以传递runnable 接口 说明构造函数支持传入一个runnable· 接口的对象
synchronized 可以对任意对象及方法上加锁。
currentTherad() 当前线程的方法
isAlive()判断当前的线程是否处于活动的状态
sleep 让正在执行的线程睡一会
getId()取得线程的唯一标识
stop()停止线程 方法已经弃用。
大多数停止一个线程的操作使用 interrupt()中止 但这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。
有三种方法可以终止正在运行的线程
1 使用退出标志,使线程正常退出,也就是run()完成后 线程终止
2 使用stop() suspend() resume()已经过时
3 使用interrupt()方法中断线程
调用interrupt()仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。

判断线程的状态是不是停止
this.interrupted() 当前线程是否已经中断
this.isInterrupted() 当前线程是否已经中断
interrupted()具有清除状态的功能
interrupted()当前线程是否已经是中断状态,执行后具有将状态标志置清除为false的功能
isInterrupted()线程thread是否已经是中断状态,但不清除状态标志

能停止的线程——异常法 interruptedException 捕获异常
在沉睡中停止线程
sleep
将方法interrupt() 与 renturn 结合使用也能实现停止线程的效果
不过还是建议使用 抛异常法来实现线程的暂停 因为在catch 块中可以对异常的信息进行相关的处理,而且使用异常流能更好的更方便的运行程序,不至于代码出现很多return 造成污染
yield()以偶的 的作用是放弃当前的cpu资源,将它让给其他的任务去占用cpu 执行时间,但放弃的时间不确定,有可能刚刚放弃,马上又获得cpu时间片。
priority()线程等级
线程的优先级具有继承性,比如a线程启动b线程 则b线程的优先级与a是一样的
高优先级线程总是大部分先执行完,但不代表高优先级的线程全部先执行完。另外,main 下滑才能所调用的就先执行完。当线程优先级的等级差距很大时,谁先执行完和代码的调用顺序无关。
因为线程的优先级还具有随机性 也就是优先级较高的线程不一定每一次都先执行完。
守护线程 没有守护线程就是线程销毁 垃圾回收也不存在了
2个线程访问同一个对象那个中的同部方法时一定是线程安全的。
A线程先持有object 对象的lock 锁 B线程可以以异步的方式调用object 对象中的非synchronized 类型的方法
A线程先持有object 对象的lock锁 B线程如果在调用object 对象中的synchronized 类型的方法则需等待 也就是同步
可重入锁:自己可以再次获取可以再次获取自己的内部锁
比如有1条线程获得了某个对象的锁 此时这个对象锁还没有释放 当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可锁重入的话,就会造成死锁。
出现异常,锁自动释放
当一个线程执行的代码出现异常时,其所持有锁会自动释放。
同步不具有继承性
同步方法 就是同步对象 同步代码块就是某个对象
代码块的上锁范围比同步方法少
当2个并发线程访问同一个对象object 中的synchronized 同步代码块时 一段时间内只能有一个线程被执行,另一个线程必须等待当前线程执行这个代码块以后才能执行该代码块。
当一个线程访问object 的一个synchronized 同步代码块时,另一个线程仍然可以访问该object 对象的非 synchronized 同步代码块 使用的对象监视器是一个
和synchronized()一样 代码块也是锁定的当前对象的
关键字volatile 的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值
synchronized 和 volatile 区别
1 volatile 是线程同步的轻量级实现,所以volatile 性能肯定比synchronized 要好 并且volatile 只能修饰于变量,而synchronized可以修饰方法,以及代码块。随着jdk新版本的额发布,synchronized 在执行效率上得到很大的提升,在研发中使用synchronized 的比率还是比较大的
2 多线程访问volatile 不会发生阻塞,而synchronized 会出现阻塞。
3 volatile 能保证数据的可见性,但不能保证原子性,而synchronized 可以保证原子性,也可以间接保证可见性,因为它会将私有内存和公共内存中的数据做同步。
4 volatile 解决的是变量在多个线程之间的可见性 而synchronized 关键字解决的是多个线程之间的访问资源的同步性。
volatile关键字 解决的是变量读时的可见性问题,但无法保证原子性,对于多个线程访问同一个实例变量还是需要加锁同步。
关键字synchronized 可以使多个线程访问同一个资源具有同步性,而且他时候具有将线程工作内存中的私有变量与公共内存中的变量同步的功能
实现多线程之间的通信,它就是wait notify 机制
wait()是使当前执行代码的线程进行等待,wait()object 类的方法 该方法用来将当前线程置入预执行队列中,并且在wait()所在的代码行出停止执行,直到接到通知或被中断为止。在调用wait()之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait() 在执行wait()后,当前线程释放锁。在wait()返回前,线程和其他线程竞争重新获得锁。如果调用wait()时没有持有适当的锁,则抛出IllegalMonitorStateException
notify()也要在同步代码或同步块中调用,即在调用前,线程也必须获得该对象的对象级别锁。如果调用notify()时没有持有适当的锁,也会抛出 IllegalMonitorStateException。该方法用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则由线程规划器随机挑选出其中一个呈wait状态的线程,对其发出通知notify 并使它等待获取该对象的对象锁。需要说明的是,在执行notify()后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获取该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出synchronized 代码块后,当前线程才会释放锁,而呈wait 状态所在的线程才可以获取该对象锁。当第一个获得了该对象锁的wait线程运行完毕后,它会释放掉该对象锁,此时吐过该对象没有再次使用notify 语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,还会继续阻塞在wait 状态 直到整个对象发出一个notify 后 notifyall
wait 使线程等待,而notify 使线程停止运行,而 notify 使停止的线程继续运行。
notify()方法执行后并不立即释放锁
优先级最高的那个线程最先执行,但也有可能是随机执行,因为这要取决于jvm虚拟机的实现。
每个锁对象都有2个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程。一个线程被唤醒后,才会进入就绪队列,等待cpu的调度;反之,一个线程被wait后,就会进入阻塞队列,等待下一次被唤醒。
当方法wait()被执行后,锁被自动释放,但执行完notify()方法,锁却不自动释放。
注意:必须执行完notify()方法所在的同步synchronized 代码块后才释放锁。

当线程呈wait()状态时,调用线程对象的interrupt()方法会出现interruptedException异常。
多次调用notify()方法唤醒了全部的warting 中的线程
带一个参数的wait(long) 方法的功能功能是等待某一个时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒。
join()的作用是等待线程对象销毁。
join()与synchronized 的区别是
join 是内部使用wait()方法进行等待 而synchronzied 关键字使用的是对象监视器 原理做为同步。
join() 与interrupt()方法如果彼此遇到,则会出现异常。
join()的功能在内部是使用wait()方法来实现的,所以join()具有释放锁的特点。
wait()释放锁 sleep()并不是释放锁
join()具有释放锁
变量值的共享可以使用public static 变量的形式,所有的线程都使用同一个public static 变量
调用reentrantLock 对象的lock()获取锁 调用unlock()释放锁
关键字synchronized 与wait()和notity notifyall()相结合可以实现等待通知模式类reentrantLock 也可以实现同样的功能,但需要借助condition 对象
condition 类是在jdk5 中出现的技术,使用他有更好的灵活性,比如可以实现多路通知功能,也就是在一个lock对象里面可以创建多个condition (即为对象监视器)实例,线程对象可以注册在指定的condition 中 从而可以有选择性地进行线程通知,在调度线程上更加灵活。
在使用notify 和 notifyall 进行通知时 被通知的线程却是有lvm 随机选择的。但使用reentrantlock 集合condition 类是可以实现前面介绍过的选择性通知 这个功能是非常重要的,而且在condition类中是默认提供的。
而synchronized 就相当于整个lock对象中只有一个单一的condition 对象,所有的线程都注册在他一个对象身上线程开始notifyall()时,需要通知所有的waiting 线程,没有选择权 会出现相当大的效率问题。
必须在condition。await()方法调用之前调用lock。lock ()代码获得对象监视器
object 类中的wait()相当于condition类中await()
object类中notify()相当于condition 类中的signal()英 [ˈsɪgnəl] sagno
object类中的notifyall()方法相当于condition类中的signalall()
condition 对象可以唤醒部分指定线程,有助于提升程序运行的效率。可以先对线程就行分组,然后在唤醒指定组中的线程。
使用reentrantlock 对象可以唤醒指定种类的线程,这是控制部分线程行为的方便方式。方法int getHoldCount()的作用是查询当前线程保持此锁定的个数,也就是调用lock()的次数
使用condition 对象可以对线程执行的业务进行排序规划
reentrantlock 一个时间只有一个锁在执行 效率低
读写锁 排它锁
多个读锁之间不互斥,读锁和写锁互斥。写锁和写锁互斥。
可以多个线程同时读取锁,只能一个线程修改锁
condition 是lock 接口下的new Condition 方法
在jdk 5出现的技术 实现多路通知功能 也就是在一个lock对象里面可以创建多个Condition(对象监视器) 可以选择性的通知线程在调用线程上更加灵活
synchronized 就相当于整个lock 对象中只有一个单一的condition 对象
ReentranttReadWriteLock
具有完全排它锁的效果 即同一时间内只有一个线程在执行ReentrantReadLock.lock()方法后面的任务
读写锁分为2种 排它锁和共享锁
多个读之间不互斥 读锁与写锁互斥 写锁与写锁互斥

wait 和 notity 是并不是马上释放 1个 锁(对象监视器) 只有当同步里面的代码全部执行完毕才能 完成释放监视器
join 可以释放锁 只能在wait 中使用
sleep 不释放锁
变量值的共享可以使用 public static 变量的形式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在多线程开发中,有几个常用的函数。其中,引用提到了委托的BeginInvoke方法以及回调函数是最常用的。委托的BeginInvoke方法可以在后台线程上异步执行方法,而回调函数则用于在后台线程执行完毕后通知主线程。另外,还有引用提到的wait()和notify()函数,它们都是Object类自带的函数。wait()函数用于使当前线程等待,直到其他线程调用notify()函数唤醒它。join()函数是另一个常用的函数,它的作用是让主线程等待子线程的终止,以便获取子线程的最终执行结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C#综合揭秘——细说多线程(上)](https://download.csdn.net/download/weixin_38628926/15548299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [二十四、多线基础(2)常用函数](https://blog.csdn.net/CaesarQu/article/details/117533962)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [EduCoder-Java高级特性 - 多线基础(2)的实现代码(关卡一到关卡三)包括对问题的总结](https://blog.csdn.net/weixin_45791445/article/details/106244219)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值