栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

一、Java后端常见面试题总结

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一、Java后端常见面试题总结

本文是一篇练习总结,记录在学习下面这份博客时的问题,并对一些相关问题进行归纳。
参考博文:java后端常见面试题总结

(一)Java基础 1. wait和sleep的区别
    这两个方法来自不同的类分别是Thread和Object最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常sleep是Thread类的静态方法。sleep的作用是让线程休眠制定的时间,在时间到达时恢复,也就是说sleep将在接到时间到达事件事恢复线程执行。wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
通信方法描述
Thread.sleep(100)sleep的作用是让线程休眠制定的时间,在时间到达时恢复,也就是说sleep将在接到时间到达事件事恢复线程执行
wait()一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。wait是Object的方法,也就是说可以对任意一个对象调用wait方法,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
notify一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程,就唤醒优先级高的线程
notifyAll一旦执行此方法,就会唤醒所有被wait()的线程

以下为题目思考部分:

这是一个多线程的问题,在学习这个问题时首先我们要对java的多线程有了解,参考博文:多线程的练习。在该博文中使用了两种方法来理解多线程问题:

① 继承Thread类的方法:
这种方法使用wait和sleep函数。

首先,创建User即创建线程,不同线程使用同一个Account。重写User的构造方法和run方法,从而决定线程的操作行为。其次,创建Account,在Account内处理线程同步问题。在Account中需要进行线程同步的方法为cunqian()方法。使用用同步代码块的方式解决线程安全问题,同步监视器为Account.class。关键代码行见下:(从中可以看出sleep和wait的区别)
这里使用notify和wait的作用是保证进程执行顺序按照先“甲”后“乙”的顺序。而synchronized的作用是线程同步,保证线程安全的。如果去掉notify和wait,只是甲乙存款的顺序会乱掉,但是由于synchronized,所以仍然可以保证线程安全。

    //存钱方法
    public void cunqian(double jine){
        if(jine>0){
            //用同步代码块的方式解决线程安全问题,同步监视器为Account.class
            synchronized (Account.class){
                Account.class.notify();
                money+=1000;
                try{
                    Thread.sleep(100);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName()+"-存款,账户余额为:"+money);
                //
                try{
                    Account.class.wait();
                }catch (InterruptedException e){
                    e.printStackTrace();
                }

            }
        }
    }

实现Runnable接口:

更多线程问题,可以参考:深入理解线程问题 2. synchronized底层原理是可重入锁吗

重入锁:所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。

synchronized 和 ReentrantLock 都是可重入锁。可重入锁的意义在于防止死锁。实现原理是通过为每个锁关联一个请求计数器和一个占有它的线程。当计数为0时,认为锁是未被占有的;线程请求一个未被占有的锁时,JVM将记录锁的占有者,并且将请求计数器置为1 。如果同一个线程再次请求这个锁,计数将递增;每次占用线程退出同步块,计数器值将递减。直到计数器为0,锁被释放。关于父类和子类的锁的重入:子类覆写了父类的synchonized方法,然后调用父类中的方法,此时如果没有重入的锁,那么这段代码将产生死锁

JVM基于进入和退出Monitor对象来显示方法同步和代码块同步,但两者的实现细节不一样。代码块同步是使用monitorenter和monitorexit指令实现的,而方法同步是使用另外一种方式实现的。monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法的结束处和异常处,JVM保证每个monitorenter必须有对应的monitorexit与之配对。

Synchronize是可重入锁,一个获得锁的线程可以再次进入一个同步块方法

参考链接:可重入锁和不可重入锁。根据链接中的代码例子,我们可以很容易地理解重入锁和不可重入锁。关键在于notify()执行在锁的数量为0时(数量大于0都不notify),还是无锁时(锁的数量只能为1或0)。

3. CAS原理,CAS会有什么问题,怎么解决ABA问题(可以谈Java内存模型)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703872.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号