十三、多线程

一、请你简述一下你对进程和线程的理解?

答:进程是指运行中的应用程序,每一个进程都有自己独立的内存空间。线程是指进程中的一个执行流程。一个进程可以由多个线程组成,即一个进程中可以同时运行多个不同的线程,它们分别执行不同的任务。

进程与线程的主要区别在于:

每个进程都需要操作系统为其分配独立的内存地址空间,而同一进程中的所有线程在同一块地址空间中工作,这些线程可以共享同一块内存和系统资源。

二、请你谈谈你对程序计数器的认识?

答:当线程执行一个方法时,程序计数器指向方法区中下一条要执行的字节码指令。

三、请你谈谈你对方法调用栈的认识?

答:简称方法栈,用来跟踪线程运行中一系列的方法调用过程,栈中的元素称为栈帧。每当线程调用一个方法时,就会向方法栈压入一个新帧,帧用来存储方法的参数、局部变量和运算过程中的临时数据。栈帧有三部分组成:

①局部变量区:存放局部变量和方法参数;

②操作数栈:是线程的工作区,用来存放运算过程中生成的临时数据。

③栈数据区:为线程执行指令提供相关的信息。

四、请你说明创建线程的方式有哪些?

答:①扩展java.lng.Thread类,覆盖run方法;

②实现Runable接口。

五、请说明你对run()方法和start()方法的认识?

答:run():包含线程运行时所执行的代码;

start():用于启动线程。

六、请你介绍一下线程的运行过程?

答:①主线程与用户自定义的线程并发执行;

②多个线程共享同一个对象的实例变量;

③不要随便覆盖Thread类的start();

创建一个线程方法后,线程不自动开始运行,必须调用它的start()方法才能启动线程。

④一个线程只能被启动一次。

七、请你描述一下线程都有哪些状态,它们之间如何转换的?

答:①新建状态

用new语句创建的线程对象处于新建状态,此时它和其他java对象一样,仅仅在堆区被分配了内存;

②就绪状态

当一个线程对象创建后,其他线程调用它的start()方法,该线程就进入就绪状态,java虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待CPU的使用权。

③运行状态

处于运行状态的线程占用CPU,执行代码。在并发运行环境中,如果计算机只有一个CPU,那么任何时候只会有一个线程处于这个状态。如果计算机有多个CPU,那么同一时刻可以让几个线程占用不同的CPU,使它们都处于运行状态。只有处于就绪状态的线程才有机会转到运行状态。

④阻塞状态

阻塞状态是指线程因为CPU,暂时停止运行。当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,他才有机会转到运行状态。阻塞状态可分为3种:

*位于对象等待池中的阻塞状态:当线程处于运行状态时,如果执行了某个对象的wait()方法,java虚拟机就会把线程放到这个对象的等待池中。

*位于对象锁池中的阻塞状态:当线程处于运行状态,试图获得某个对象的同步锁,如果该对象的同步锁已经被其他线程占用,java虚拟机就会把这个线程放到这个对象的锁池中。

*其他阻塞状态:当前线程执行了sleep()方法,或者调用了其他线程的join()方法,或者发出了I/O请求时,就会进入这个状态。

⑤结束状态

当线程退出run()方法以后,就进入结束状态,该线程结束生命周期。

八、请问线程的调度是什么?有什么调度模型?

答:线程的调度是指按照特定的机制为多个线程分配CPU的使用权,有两种调度模型:分时调度模型和抢占式调度模型。

分时调度模型是指让所有线程轮流获得CPU使用权,并且平均分配每个线程占用CPU的时间片。

java虚拟机采用抢占式调度模型,它是指优先让可运行池中优先级高的线程占用CPU,如果可运行池中线程的优先级相同,那么就随机地选择一个线程,使其占用CPU。

九、请问如何让一个线程给另外一个线程运行的机会?

答:①调整各个线程的优先级;

②让处于运行状态的线程调用Thread.sleep()方法;

当一个线程在运行中执行了sleep()方法,他就会放弃CPU,转到阻塞状态。

③让处于运行状态的线程调用Thread.yield()方法;

当线程在运行中执行了Thread类的yield()静态方法时,如果此时具有相同或更高优先级的其他线程处于就绪状态,yield()方法将把当前运行的线程放到可运行池中并使另一个线程运行。如果没用相同优先级的可运行线程,yield()方法什么都不做。

④让处于运行状态的线程调用另一个线程的join()方法。

当前运行的线程可以调用另一个线程的join()方法,当前运行的线程将转到阻塞状态,直至另一个线程运行结束,它才会恢复运行。

十、请问sleep()方法和yield()方法有什么共同点或不同点?

答:相同点:它们都是Thread类的静态方法,都会使当前处于运行状态的线程放弃CPU,把运行机会让给别的线程。

区别:①sleep()方法会给其他线程运行的机会,不考虑其他线程的优先级,因此会给较低优先级线程一个运行机会。

yield()方法只会给相同优先级或者更高优先级的线程一个运行的机会。

②当线程执行了sleep(long millis)方法以后,将转到阻塞状态;

当线程执行了yield()方法后,将转到阻塞状态;

③sleep()方法声明抛出InterruptedException异常;

而yield()方法没有声明抛出任何异常。

④sleep()方法比yield()方法具有更好的可移植性。yield()方法的唯一用途是在测试期间人为地提高程序的并发性能,以帮助发现一些隐藏的错误。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值