java面试-多线程&并发篇1-多线程,停止线程,线程可见性,线程启动(1-6,共29)

2020-05-18 12:32:35 445
声音简介

你好,今天我要和您分享的是java面试--多线程和并发篇(1-6个小节,共29个小节),


在上期当中,我们学习了 JVM篇的:


Java垃圾回收机制

什么是类加载器,

类加载器有哪些,

jvm内存不足如何处理,

JDK 1.8之后永久代Perm Space有哪些变动,

JVM内存相关的几个核心参数,

如何启动系统的时候设置JVM的启动参数



今天我们来学习:


Java中实现多线程有几种方法,

如何停止一个正在运行的线程,

notify()和notifyAll()有什么区别,

sleep()和wait() 有什么区别,

volatile 是什么?可以保证有序性吗,

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



那话不多说,我们开始学习吧




1、Java中实现多线程有几种方法

1.1、继承Thread类;

1.2、实现Runnable接口;

1.3、实现Callable接口通过FutureTask包装器来创建Thread线程;

1.4、使用ExecutorService、Callable、Future实现有返回结果的多线程(也就是使用了ExecutorService来管理前面的三种方式)。


2、如何停止一个正在运行的线程


2.1、使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。


2.2、使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。


2.3、使用interrupt方法中断线程,推荐用这种方法

interrupt只是改变中断状态,不会中断一个正在运行的线程,他的作用是中断线程。将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程


class MyThread extends Thread { volatile boolean stop =false; publicvoidrun() { while (!stop) { System.out.println(getName() +" is running"); try { sleep(1000); } catch (InterruptedException e) { System.out.println("week up from blcok..."); stop =true; // 在异常处理代码中修改共享变量的状态 } } System.out.println(getName() +" is exiting..."); }} classInterruptThreadDemo3 { publicstaticvoidmain(String[] args) throws InterruptedException { MyThread m1 =new MyThread(); System.out.println("Starting thread..."); m1.start(); Thread.sleep(3000); System.out.println("Interrupt thread...: "+ m1.getName()); m1.stop =true; // 设置共享变量为true m1.interrupt(); // 阻塞时退出阻塞状态 Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断情况 System.out.println("Stopping application..."); }}


3、notify()和notifyAll()有什么区别?


notify可能会导致死锁,而notifyAll则不会

任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码

使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。


wait() 应配合while循环使用,不应使用if,务必在wait()调用前后都检查条件,如果不满足,必须调用notify()唤醒另外的线程来处理,自己继续wait()直至条件满足再往下执行。


notify() 是对notifyAll()的一个优化,但它有很精确的应用场景,并且要求正确使用。不然可能导致死锁。正确的场景应该是 WaitSet中等待的是相同的条件,唤醒任一个都能正确处理接下来的事项,如果唤醒的线程无法正确处理,务必确保继续notify()下一个线程,并且自身需要重新回到WaitSet中.


4、sleep()和wait() 有什么区别?


对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。


sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。


当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备,获取对象锁进入运行状态。


5、volatile 是什么?可以保证有序性吗?


一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:


1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的,volatile关键字会强制将修改的值立即写入主存。


2)禁止进行指令重排序。

volatile 不是原子性操作

什么叫保证部分有序性?

当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,而且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

请返回文稿查看示例代码,总共有5行代码,volatile变量在第三行

x =2; //语句1 

y =0; //语句2 

flag =true//语句3 

x =4//语句4 

y =-1;//语句5

由于flag变量为volatile变量,那么在进行指令重排序的过程的时候,不会将语句3放到语句1、语句2前面,也不会将语句3放到语句4、语句5后面。但是要注意语句1和语句2的顺序、语句4和语句5的顺序是不作任何保证的。

使用 Volatile 一般用于 状态标记量 和 单例模式的双检锁


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

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


好了,今天我们学习了:

Java中实现多线程有几种方法,

如何停止一个正在运行的线程,

notify()和notifyAll()有什么区别,

sleep()和wait() 有什么区别,

volatile 是什么?可以保证有序性吗,

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


希望对你所帮助,我们下期再见


坚持学习,加油


用户评论

表情0/300
喵,没有找到相关结果~
暂时没有评论,下载喜马拉雅与主播互动
猜你喜欢
【下载器】Java多线程项目实战-熟练应用多线程技术

资料获取方式:+v号java1060视频资料获取方式在专辑第一条视频下方评论区处!!!对于学习完JavaSE特别是多线程技术后想捣鼓点自己的东西,想找个项目实战...

by:动力节点教育

Java多线程高并发编程马士兵老师

全部视频源码笔记在微信公众号:程序员理想,全套资料视频或更多大数据,java,java架构师,区块链,等等资料也在微信公众号:程序员理想

by:优效学院Java架构嘿

【完整版】动力节点Java多线程实战教程全集

资料获取方式:+v号java1060线程是进程中的一个独立控制单元,线程在控制着进程的执行,一个进程中至少有一个线程。多线程可以更好地利用cpu的资源,线程之间...

by:动力节点教育

java面试

高质量面试题逐字逐句整理,若需要音频同步资料,请扫专辑二维码进群领取

by:昔玛蜡瓦

Java面试

2024年的java面试知识总结,内容包含了Java基础、集合类、Java并发、JVM、Spring、SpringCloud、MySQL、Mybatis、Tom...

by:小爱和云天

JAVA面试题

java码农基础面试题,搞定面试

by:摔了不痛

2020年JAVA面试208题

面试是类似演讲演说的过程,网上的面试资料都是文字的,没办法让面试者直观的体验到面试过程,希望这个音频节目对你有帮助。纯粹硬核IT知识,技术小白请绕路。搜集整理各...

by:小崔爱读书

java面试特训营|随时随地学面试

不论你是否在找工作,都要时刻保持竞争力,掌握好java面试技能,随心所欲,找工作无惧1、一对一课程规划,避免盲目乱整浪费时间2、专业简历修改,高质量简历一投就中...

by:码农那点事