【java面试私房菜】线程

阅读: 评论:0

【java面试私房菜】线程

【java面试私房菜】线程

文章目录

    • 线程
      • 一、进程与线程
      • 二、创建线程
        • 1.创建线程的有哪些方式?
        • 2.创建线程的三种方式的对比?
        • 3.sleep() 、wait()、yield() 有什么区别?
        • 4.线程具有五种基本状态
    • 三、示例代码

线程

一、进程与线程

进程是指程序(任务)的执行过程,持有资源(共享内存、共享文件)和线程。
线程是指系统中最小的执行单元。同一进程中有多个线程,线程共享资源

二、创建线程

1.创建线程的有哪些方式?

1)继承Thread类创建线程类
2)通过Runnable接口创建线程类
3)通过Callable和Future创建线程
4)通过线程池创建

2.创建线程的三种方式的对比?

1)采用实现Runnable、Callable接口的方式创建多线程。
优势是:
线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
劣势是:
编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

2)使用继承Thread类的方式创建多线程
优势是:
编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
劣势是:
线程类已经继承了Thread类,所以不能再继承其他父类。

3)Runnable和Callable的区别
Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。
Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
Call方法可以抛出异常,run方法不可以。
运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

3.sleep() 、wait()、yield() 有什么区别?

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。

wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源),并执行其他线程。

yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

4.线程具有五种基本状态

1)新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

2)就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行

3)运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

4)阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。
根据阻塞产生的原因不同,阻塞状态又可以分为三种:
a.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
b.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
c.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5)死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

三、示例代码

摘自慕课网课程

package urrent.base;//军队线程
//模拟作战双方的行为
public class ArmyRunnable implements Runnable {//volatile保证了线程可以正确的读取其他线程写入的值//可见性 ref JMM, happens-before原则volatile boolean keepRunning = true;@Overridepublic void run() {while(keepRunning){//发动5连击for(int i=0;i<5;i++){System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]");//让出了处理器时间,下次该谁进攻还不一定呢!Thread.yield();}		}System.out.println(Thread.currentThread().getName()+"结束了战斗!");}
}
package urrent.base;public class KeyPersonThread extends Thread {public void run(){System.out.println(Thread.currentThread().getName()+"开始了战斗!");for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+"左突右杀,攻击隋军...");}System.out.println(Thread.currentThread().getName()+"结束了战斗!");}
}
package urrent.base;/*** 隋唐演义大戏舞台*/
public class Stage extends Thread {public void run(){System.out.println("欢迎观看隋唐演义");//让观众们安静片刻,等待大戏上演try {Thread.sleep(5000);} catch (InterruptedException e1) {e1.printStackTrace();}System.out.println("大幕徐徐拉开");try {Thread.sleep(5000);} catch (InterruptedException e1) {e1.printStackTrace();}System.out.println("话说隋朝末年,隋军与农民起义军杀得昏天黑地...");ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable();ArmyRunnable armyTaskOfRevolt = new ArmyRunnable();//使用Runnable接口创建线程Thread  armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军");Thread  armyOfRevolt = new Thread(armyTaskOfRevolt,"农民起义军");//启动线程,让军队开始作战armyOfSuiDynasty.start();armyOfRevolt.start();//舞台线程休眠,大家专心观看军队厮杀try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("正当双方激战正酣,半路杀出了个程咬金");Thread  mrCheng = new KeyPersonThread();mrCheng.setName("程咬金");System.out.println("程咬金的理想就是结束战争,使百姓安居乐业!");//停止军队作战//停止线程的方法armyTaskOfSuiDynasty.keepRunning = false;armyTaskOfRevolt.keepRunning = false;try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}/** 历史大戏留给关键人物*/mrCheng.start();//万众瞩目,所有线程等待程先生完成历史使命try {mrCheng.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("战争结束,人民安居乐业,程先生实现了积极的人生梦想,为人民作出了贡献!");System.out.println("谢谢观看隋唐演义,再见!");}public static void main(String[] args) {new Stage().start();}}

本文发布于:2024-01-30 21:13:46,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170662042822885.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   私房   java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23