首页 > 编程语言 >Java基础知识五

Java基础知识五

时间:2023-09-11 17:33:04浏览次数:45  
标签:Runnable Java 基础知识 线程 进程 多线程 方法

1.什么是线程?

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。


2.线程和进程有什么区别?

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。

不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间


3.线程的五大状态?线程的生命周期

创建状态(New):用三种方式创建线程,还没有调用start。

就绪状态(Runnable):在创建了线程之后,调用Thread类的start()方法来启动一个线程,即表示线程进入就绪状态。

运行状态(Running):当线程获得CPU时间,线程才从就绪状态进入到运行状态

阻塞状态(Blocked):运行中的线程进入阻塞状态,如调用sleep()方法让线程睡眠,调用wait()方法让线程等待等。

终止状态(Dead):当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。


4.如何在Java中实现线程

继承java.lang.Thread 类

实现Runnable接口

实现Callable<>接口

通过线程池创建线程


5.用Runnable还是Thread?

大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使 用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好了。


6.Thread 类中的start() 和 run() 方法有什么区别?

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启 动,start()方法才会启动新线程


7.Java中Runnable和Callable有什么不同?

Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在 JDK1.5增加的。它们的主要区别是Callable的 call() 方法可以返回值(Future对象)和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。

Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。


8.什么是线程池? 为什么要使用它?

创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时 候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池

线程池的参数配置

第一个参数为corePoolSize 核心线程数

第二个参数为maximumPoolSize 最大线程数

第三个参数为keepAliveTime 线程的保存时间

第四个参数为queue:用来定义等待任务队列的属性


9.Java中notify 和 notifyAll有什么区别?

notify()方法不能唤醒某个具体的线程,所以只有一个线程在等 待的时候它才有用武之地。而notifyAll()唤醒所有线程并允许他们争夺锁确保了至少有一个线程能继续运行。


当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。


10.如何避免死锁?

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:


互斥条件:一个资源每次只能被一个进程使用。

请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。


11.什么是线程安全?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量 的值也和预期的是一样的,就是线程安全的。


12.多线程是什么?

在介绍多线程的时候,我们首先要知道什么是线程,而要了解线程还要了解进程。

1.进程:一个正在执行中的程序,每个进程执行都有一个执行顺序

2.线程:进程中的一个独立控制单元,线程在控制进程的执行。一个进程中至少有一个线程。

3.多线程:一个进程中不只有一个线程。


13.我们为什么要用多线程呢?

为了更好地利用CPU的资源,如果只有一个线程,我们有多个任务的时候必须等着上一个任务完成才能进行。多线程则不用等待可在主线程执行的同时执行其他任务。(可同时执行多个线程效率高)

进程之间不可以共享数据,但是 线程可以。(可共享数据)

系统创建进程需要为该进程重新分配系统资源,创建线程代价少。

Java语言内置了多线程功能支持,简化了Java多线程编程。


14.什么是悲观锁

总是假设最坏的情况,每次拿数据的时候都会认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人想要拿这个数据的时候就会因为加锁了而阻塞,直到他拿到锁。

悲观锁核心思想:共享资源每次只给一个线程使用,其他进程阻塞,用完后再把资源转让给其他的进程。

关系型数据库很多都用到了悲观锁机制,Java中synchronized 和 ReetrontLock 是悲观锁


15.什么是乐观锁

总是假设最好的情况,每次拿数据的时候都会认为别人不会修改,所以不会上锁。但是在更新的时候回先判断一下

别人有没有更新这个数据,可以使用 版本号控制机制和CAS算法实现,乐观锁适用于多读的应用类型,这样可以提高吞吐量。


16.两种锁的使用场景

乐观锁适用于少写多读的情况,多读冲突少可以省去锁的开销提高吞吐量,多写的情况使用悲观锁比较安全


17.乐观锁的版本号机制(Redis中使用)

一般在数据表中加上一个数据版本号的字段version,表示数据被修改的次数,当数据被修改的时候version+1,当数据更新的时候,读取数据的同时也会读取版本号,更新数据时,若当前读到的version和数据库中存储的version一致的时候说明,在更新期间没有别的线程操作此数据,此时允许更新。如果version不一致,说明更新期间数据被其他线程修改了,此时不允许更新。


18sleep和wait的区别

1.sleep不会释放对象锁。Wait会释放锁

2.sleep会自动唤醒。wait需要其它线程唤醒。

3.sleep是Thread中的方法。wait是Object中的方法。

4.sleep可以在任何地方使用,而wait只能在同步方法或者同步块中使用。


19.公平锁

定义:

公平锁是指多个线程按照申请锁的顺序来获得锁,线程直接进入队列中排队,队列中的第一个线程才能获得锁


优点

等待锁的线程不会饿死。


缺点

整体吞吐效率比非公平锁要低,等待队列中除第一个以外的线程都会阻塞,CPU唤醒阻塞线程的开销比非公平锁要大。

公平锁排队的理解:如图,新来了一个D,D要进行排队,排到队列的最后面,最后来的最后获得锁




20.非公平锁

概念

非公平锁是多个线程加锁时直接尝试获得锁,获取不到才会进入等待队列的队尾等待。但如果此时锁刚好可用,那么这个线程可以无需阻塞直接获取到锁,所以非公平锁有可能出现后申请锁的线程先获得锁的场景。

优点

可以减少唤醒线程的开销,整体吞吐效率高,因为线程有几率不阻塞直接获得锁。

缺点

处于等待队列中的线程可能会饿死,或者等很久才会获得锁。


21.锁的分类

锁一般的分类有:同步锁、互斥锁、悲观锁、乐观锁、公平锁、非公平锁。

java中,一把锁可能同时占有多个标准,符合多种分类

偏向锁/轻量级锁/重量级锁:这三种锁特指synchronized锁的状态


偏向锁

它的思想是如果自始至终,对于这把锁都不存在竞争,那么其实就没必要上锁,只要打个标记就行了。有点类似于乐观锁的机制,乐观锁就是默认不竞争,没必要上锁。但是他不是乐观锁。

偏向锁概念:

一个对象在被初始化后,如果还没有任何线程来获取它的锁时,它就是可偏向的,当有第一个线程来访问它尝试获取锁的时候,它就记录下来这个线程,如果后面尝试获取锁的线程正是这个偏向锁的拥有者,就可以直接获取锁,开销很小。


轻量级锁(CAS)

JVM 的开发者发现在很多情况下,synchronized 中的代码块是被多个线程交替执行的,也就是说,并不存在实际的竞争,或者是只有短时间的锁竞争,用 CAS 就可以解决

偏向锁升级到轻量级锁

这种情况下,重量级锁是没必要的。轻量级锁指当锁原来是偏向锁的时候,被另一个线程所访问,说明存在竞争,那么偏向锁就会升级为轻量级锁,线程会通过自旋的方式尝试获取锁,不会阻塞。


重量级锁(阻塞)

会对拿不到锁的线程进行阻塞

这种锁利用操作系统的同步机制实现,所以开销比较大。当多个线程直接有实际竞争,并且锁竞争时间比较长的时候,

此时偏向锁和轻量级锁都不能满足需求,锁就会膨胀为重量级锁。重量级锁会让其他申请却拿不到锁的线程进入阻塞状态

标签:Runnable,Java,基础知识,线程,进程,多线程,方法
From: https://blog.51cto.com/u_16243779/7437469

相关文章

  • Unity 游戏开发、01 基础知识大全、简单功能脚本实现
    2.3窗口布局Unity默认窗口布局Hierarchy层级窗口Scene场景窗口,3D视图窗口Game游戏播放窗口Inspector检查器窗口,属性窗口Project项目窗口Console控制台窗口恢复默认布局Window|Layouts|Default调大页面字体Preference|UIScaling3.1场景新项......
  • 你不知道的JavaScript(上中下三卷)pdf
    不错的书网盘mark一下https://pan.quark.cn/s/c8b525946add......
  • 无涯教程-JavaScript - MIRR函数
    描述MIRR函数针对一系列定期现金Stream返回修改后的内部收益率。MIRR会同时考虑投资成本和现金再投资收到的利息。语法MIRR(values,finance_rate,reinvest_rate)争论Argument描述Required/OptionalValues包含数字的单元格的数组或引用。这些数字表示定期发生的一......
  • java复习记录点
    类型转换int类型转二进制:Integer.toBinaryString(int);进制解析(其他进制转十进制):Integer.parseInt(String,int);//将string看成是以int进制的string,并以10进制输出结果进制解析(十进制转其他进制):Integer.toHexString(int);返回绝对值:Math.abs();*正则:[a-zA-Z]英文......
  • java开发之个微机器人助手的开发
    简要描述:群管理操作请求URL:http://域名/operateChatRoom请求方式:POST请求头Headers:Content-Type:application/jsonAuthorization:login接口返回参数:参数名必选类型说明wId是String登录实例标识chatRoomId是String群wcId是String群成员微信id,多个用","分割type是int1:添加群管理(可添......
  • linux基础知识
    文件结构及其作用/boot:引导文件存放目录,内核文件(vmlinuz)、引导加载器(bootloader,grub)都存放于此目录/bin:所有用户使用的基本命令;不能关联至独立分区,OS启动即会用到的程序/sbin:管理类的基本命令;不能关联至独立分区,OS启动即会用到的程序/lib:启动时程序依赖的基本共享库文件......
  • 无涯教程-JavaScript - MDURATION函数
    描述MDURATION函数返回假定面值为$100的有价证券的经修改Macaulay期限。语法MDURATION(settlement,maturity,coupon,yld,frequency,[basis])争论Argument描述Required/OptionalSettlement证券的结算日期。证券结算日期是指在发行日期之后将证券交易给买方的日......
  • 【JAVA日常】关于jeecgBoot @Dict注解的使用不生效问题
    项目中后端使用jeecgBoot开发,最近正好遇到一些关于改造和使用@dict字典注解的问题,正好记录一下,以防忘记。1、注解不生效问题1今天公司同事问,说这个注解加上了怎么还不起作用呢。我们就检查了代码中的使用。注解的添加以及使用都正常,然后排查发现接口调用时未执行字典的切面,那么......
  • tomcat出现Java heap space / PermGen space解决方法(详解)
    使用Java程序从数据库中查询大量的数据时出现异常:java.lang.OutOfMemoryError:Javaheapspace在JVM中如果98%的时间是用于GC且可用的Heapsize不足2%的时候将抛出此异常信息。JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap......
  • 如何使用 Idea 远程调试 Java 代码
    ​服务端配置首先,我们要让要让远程服务器支持远程调试功能,在项目启动项上追加特定的JVM参数即可,参数如下:晚于JDK1.4.X版本1-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=4001JDK1.4.X版本1-Xdebug-Xrunjdwp......