【Java面试】第六天

在这里插入图片描述

🌟个人主页:时间会证明一切.


线程有几种状态,状态之间的流转是怎样的?

Java中线程的状态分为6种:
1.初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2.运行(RUNNABLE):Java线程中将就绪(READY)和运行中(RUNNING)两种状态笼统的称为“运行”。
就绪(READY):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中并分配cpu使用权 。
运行中(RUNNING):就绪(READY)的线程获得了cpu 时间片,开始执行程序代码。
3.阻塞(BLOCKED):表示线程阻塞于锁(关于锁,在后面章节会介绍)。
4.等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5.超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。
状态流转如图:
image.png

WAITING和TIMED_WAIT的区别?

WAITING是等待状态,在Java中,调用wait方法时,线程会进入到WAITING状态,而TIMED_WAITING是超时等待状态,当线程执行sleep方法时,线程会进入TIMED_WAIT状态。

处于WAITING和TIMED_WAIT的线程,都是会让出CPU的,这时候其他线程就可以获得CPU时间片开始执行。但是他们在对象的锁释放上面并不一样,如果加了锁,sleep方法不会释放对象上的锁,而wait方法是会释放锁的。

因为Java锁的目标是对象,所以wait、notify和notifyAll针对的目标都是对象,所以把他们定义在Object类中。而sleep不需要释放锁,所以他是Thread类中的一个方法。

为什么线程没有RUNNING状态

对于现在的分时操作系统来说,在单CPU情况下,所有的线程其实都是串行执行的。但是为了让我们看起来像是在并发执行,人们把CPU的执行分成很多个小的时间片。

哪个线程得到时间片,那个线程就执行,时间片到了之后,就要释放出CPU,再重新进行争抢时间片。

只要把时间片划分的足够细,那么多个程序虽然在不断的串行执行,但是看起来也像是在同时执行一样。

image.png

那么,CPU的时间片其实是很短的,一般也就是10-20毫秒左右。

那么,也就是说,在一秒钟之内,同一个线程可能一部分时间处于READY状态、一部分时间处于RUNNING状态。

那么如果,明确的给线程定义出RUNNING状态的话,有一个很大的问题,就是这个状态其实是不准的。

因为当我们看到线程是RUNNING状态的时候,很有可能他已经丢失了CPU时间片了。

对于线程的状态,我们只需要知道,他当前有没有在"正在参与执行"就行了,何为"参与执行"?

就是他的状态是可执行的,只要获得时间片,就能立即执行。

那这不就是RUNNABLE吗?

所以,Java就没有给线程定义RUNNING状态,而是定义了一个RUNNABLE状态。

什么是死锁,如何解决?

死锁是指两个或两个以上的进程(或线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

比如:丈母娘要求先买房才能结婚,但是女婿说先结婚买房

产生死锁的四个必要条件

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不可强行占有:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:**若干进程之间形成一种头尾相接的循环等待资源关系。

如何解除死锁

想好解除和预防死锁,就避免4个条件同时发生就行了,一般从以下几个方面入手

破坏不可抢占:设置优先级,使优先级高的可以抢占资源

破坏循环等待:保证多个进程(线程)的执行顺序相同即可避免循环等待。
如执行顺序都是:A->B->C,那就可以避免循环等待。
最常用的避免方法就是破坏循环等待,就是当我们有多个事务的时候,最好让这几个事务的执行顺序相同。
如事务1:A->B->C ,事务2:C->D->A,这种情况就有可能导致死锁。
即事务1占有了A,等待C,而事务2占有了C在等待A。
所以,要避免死锁就把事务2改为:A -> D-> C。

数据库死锁的发生

在数据库中,如果有多个事务并发执行,也是可能发生死锁的。当事务1持有资源A的锁,但是尝试获取资源B的锁,而事务2持有资源B的锁,尝试获取资源A的锁的时候,这时候就会发生死锁的情况。

发生死锁时,会发生如下异常:

Error updating database. Cause: ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] 

Deadlock found when trying to get lock; 

一般对于数据库的死锁,主要是避免发生并发修改。或者可以考虑保证操作的顺序,比如多个事务都是先操作资源A、再操作资源B,这样就能有效的避免死锁。

什么是并发,什么是并行?

并发(Concurrent),在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。

那么,操作系统是如何实现这种并发的呢?

现在我们用到操作系统,无论是Windows、Linux还是MacOS等其实都是多用户多任务分时操作系统。使用这些操作系统的用户是可以“同时”干多件事的。

但是实际上,对于单CPU的计算机来说,在CPU中,同一时间是只能干一件事儿的。为了看起来像是“同时干多件事”,分时操作系统是把CPU的时间划分成长短基本相同的时间区间,即”时间片”,通过操作系统的管理,把这些时间片依次轮流地分配给各个用户使用。

如果某个作业在时间片结束之前,整个任务还没有完成,那么该作业就被暂停下来,放弃CPU,等待下一轮循环再继续做.此时CPU又分配给另一个作业去使用。

由于计算机的处理速度很快,只要时间片的间隔取得适当,那么一个用户作业从用完分配给它的一个时间片到获得下一个CPU时间片,中间有所”停顿”,但用户察觉不出来,好像整个系统全由它”独占”似的。

所以,在单CPU的计算机中,我们看起来“同时干多件事”,其实是通过CPU时间片技术,并发完成的。

提到并发,还有另外一个词容易和他混淆,那就是并行。

并发与并行之间的关系

并行(Parallel),当系统有一个以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

Erlang 之父 Joe Armstrong 用一张比较形象的图解释了并发与并行的区别:

并发是两个队伍交替使用一台咖啡机。并行是两个队伍同时使用两台咖啡机。

映射到计算机系统中,上图中的咖啡机就是CPU,两个队伍指的就是两个进程。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值