2021-05-31

day23

学习内容
一:线程同步
1.1、同步代码块
锁多条语句操作共享数据,可以使用同步代码块实现

格式:
synchonie(任意对象){
多条语句操作共享数据的代码

synchronie(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁。
同步的好处和弊端:

好处: 解决了多线程的数据安全问题。
弊端: 当线程很多时,因为每个线程都会去判断同步上的锁。这是很耗费资源的。无形中会降低程序的运行效率。
1.2、同步方法
同步方法: 就是把synchronined关键字加到方法上

格式
修饰符sychonred 返四值类型 方法名(方法参数){ }

this
同步静态方法 :就是synchronized以关键字加到静态方法上

格式:
修饰符static synchronized返四值类型 方法名(方法参数){}

Lock锁

Lock锁,可以得到和 synchronized一样的效果,即实现原子性、有序性和可见性。
相较于synchronized,Lock锁可手动获取锁和释放锁、可中断的获取锁、超时获取锁。
Lock 是一个接口,两个直接实现类:ReentrantLock(重入锁), ReentrantReadWriteLock(读写锁)。
Lock锁,使用时手动获取锁和释放锁,比synchronized更加灵活;可中断的获取锁;超时获取锁。
Lock 锁的基本用法, l.lock()方法进行上锁, l.unlock()方法进行解锁

二:线程状态(waiting)
六大主要线程状态

NEW(新建)

线程刚被创建, I但是并未启动。还没调用start方法。

Runnable(可

线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操

运行)

作系统处理器。

Blocked(锁阻

当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状

塞)

态;当该线程持有锁时,该线程将变成Runnable状态。

Waiting(无限

-一个线程在等待另一一个线程执行-一个(唤醒)动作时,该线程进入Waiting状态。进入这个

等待)

状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyAIl方法才 能够唤醒。

Timed

同waiting状态,有几个方法有超时参数,调用他们将进入Timed Waiting状态。这一-状态

Waiting(计时

将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep、

等待)

Object.wait.

Teminated(被

因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

终止)

我们不需要去研究这几种状态的实现原理,我们只需知道在做线程操作中存在这样的状态。那我们怎么去理解这几个状态呢,新建与被终止还是很容易理解的,我们就研究一下线程从Runnable (可运行)状态与非运行状态之间的转换问题。

无限等待状态的前提

该线程必须获取了锁对象
调用线程的wait方法,那么锁对象的持有者就会无限等待了
同时该线程会释放锁,别的线程就有机会获取锁对象了
那么该线程得到锁对象后,就可以调用锁对象的notify/notifyAll方法,唤醒刚刚进入无限等待的线程对象
需要注意的是:被唤醒的线程,并不会进入Runnable,因为没有锁对象,只有其他线程释放了锁对象并且被唤醒的线程获取到了锁对象该线程才会真正的进去Runnable状态
无限等待真的是无限的吗?作为初学者,一定不能被表面的单词所迷惑!!! 其实这里的无限等待是指线程不会自动"醒来"(不像sleep那样,时间到了就会自动"醒来"), 但是别的线程可以"唤醒"它 上面我们提到,处于Waiting状态的线程会释放锁对象,那么其他线程就有机会获取锁对象
另:
其实waiting状态并不是一个线程的操作,它体现的是多个线程间的通信,可以理解为多个线程之间的协作关系, 多个线程会争取锁,同时相互之间又存在协作关系。就好比在公司里你和你的同事们,你们可能存在晋升时的竞 争,但更多时候你们更多是一起合作以完成某些任务。 当多个线程协作时,比如A,B线程,如果A线程在Runnable(可运行)状态中调用了wait()方法那么A线程就进入 了Waiting(无限等待)状态,同时失去了同步锁。假如这个时候B线程获取到了同步锁,在运行状态中调用了 notify()方法,那么就会将无限等待的A线程唤醒。注意是唤醒,如果获取到锁对象,那么A线程唤醒后就进入 Runnable(可运行)状态;如果没有获取锁对象,那么就进入到Blocked(锁阻塞状态)
Timed Waiting (计时等待)

Timed Waiting在API中的描述为: -一个正在限时等待另一个线程执行-一个(唤醒)动作的线程处于这一状态。单独的去理解这句话,真是玄之又玄,其实我们在之前的操作中已经接触过这个状态了,在哪里呢?

在我们写卖票的案例中,为了减少线程执行太快,现象不明显等问题,我们在run方法中添加了sleep语句,这样就强制当前正在执行的线程休眠(暂停执行) ,以“减慢线程"。

其实当我们调用了sleep方法之后,当前执行的线程就进入到“休眠状态”,其实就是所谓的Timed Waiting(计时等待),那么我们通过一一个案例加深对该状态的一个理解。

实现-个计数器,计数到100, 在每个数字之间暂停1秒,每隔10个数字输出-一个字符串
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值