2022-8-3 第七组 潘堂智 锁、多线程
锁
1.synchronized多线程并发编程。
重量级锁。JDK1.6对synchronized进行了优化。
JDK1.6为了减少获得锁和释放锁带来的性能消耗引入的偏向锁和轻量级锁。
synchronized有三种方式来加锁,分别是:
- 1.修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
- 2.静态方法,作用于当前类对象加锁,进入同步代码前要获得的当前类对象的锁
- 3.代码块,指定加锁对象,对给定对象加锁,进入同步代码块之前要获得给定对象的锁
对于普通同步方法,锁是当前实例对象(对象锁)
对于静态同步方法,锁是当前类Class对象(类锁)
对于同步方法块,锁是Synchronized括号里配置的对象
join的作用就是,调用join的线程等一等,等我跑完,你再继续跑。
在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将可能早于子线程结束。如果主线程需要知道子线程的执行结果时,就需要等待子线程执行结束了。
主线程可以sleep(xx),但这样的xx时间不好确定,因为子线程的执行时间不确定,join()方法比较合适这个场景。
死锁
死锁是这样一种情形:多个线程同时被阻塞,他们中的一个或者全部
都在等待某个资源的释放,由于线程无限期的阻塞,程序就不可能正常终止。
java死锁产生四个必要条件
* 1.互斥使用,当资源被一个线程使用(占用),别的线程不能使用。
* 2.不可抢占,资源请求者不能强制从占有者中抢夺资源,资源只能从占有者
* 手动释放
* 3.请求和保持,
* 4.循环等待,存在一个等待队列。P1占有P2的资源,P2占有了P3的资源
* P3占有P1的资源。形成了一个等待环路。
JDK1.6以后锁升级:
* 1.无锁:不加锁
* 2.偏向锁:不锁锁,只有一个线程争夺时,偏向某一个线程,这个线程不加锁
* 3.轻量级锁:少量线程来了之后,向尝试自旋,不挂起线程。
* 4.重量级锁:排队挂起(暂停)线程。(synchronized)
1.偏向锁
HotSpot的作者经过研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功,表示线程已经获得了锁。如果测试失败,则需要再测试一下Mark Word中偏向锁的标识是否设置成1(表示当前是偏向锁):如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。
2.轻量级锁
线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mark Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
3.重量级锁
内置锁在Java中被抽象为监视器锁(monitor)。在JDK 1.6之前,监视器锁可以认为直接对应底层操作系统中的互斥量(mutex)。这种同步方式的成本非常高,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。因此,后来称这种锁为“重量级锁”。
线程重入
* 任意线程在拿到锁之后,再次获取该锁不会被该锁所阻碍
*
* 线程不会被自己锁死的。
* 这就叫线程的重入,synchronized可重入锁。
* 1.Thread的两个静态方法:
* sleep释放CPU资源,但是不会释放锁
* yield方法释放CPU执行权,保留了CPU的执行资格,不常用。
* 2.join方法,yield出让了执行权,join就加入进来。
* 3.wait:释放CPU资源,释放锁
* notify:唤醒等待中的线程
* notifyAll:唤醒等待中的所有线程
线程的常用方法:
* Thread类中的方法
* 1.start:启动当前线程;执行run方法
* 2.run:
* 3.currentThread:静态方法,获取当前正在执行的线程
* 4.getId():返回此线程的唯一标识
* 5.setName(String):设置当前线程的name
* 6.getName():获取当前线程的name
* 7.getPriority():获取当前线程的优先级
* 8.setPriority(int):设置当前线程的优先级
* 9.getState():获取当前线程的声明周期
* 10.interrupt():中断线程的执行
* 11.interrupted():查看当前线程是否中断
本文来自博客园,作者:阿萨德菩提子,转载请注明原文链接:https://www.cnblogs.com/ychptz/p/16548252.html