面试总结栈长最近面试了一位有5年经验的Java程序员。他的简历和个人介绍都提到了精通Java多线程,所以问了几个关于多线程的问题:1、实现多线程有什么好处?哪些方法以及如何返回结果?2、多线程如何实现顺序访问?3、两个线程如何交换数据?4、如何统计5个线程的总运行时间?5、如何将一个任务拆分成多个子任务执行,最后合并结果?我可能问过他这些问题,但他没有很好地回答。问题3、4、5他并没有真正回答,其实这些问题在JDK包中都有答案,只是他给出的是个人的临时思考。解决方案,我个人认为可能行不通。我已经工作5年了,我不能很好地回答这些问题。这有点不合理。我真的醉了。.其中,我在公众号Java技术栈分享了1、2、4、5题的相关教程,我也整理在了Java面试库小程序中。看看最近的采访,今天分享第三篇。参考问题答案。问题3也是通过JDK中的java.util.concurrent.Exchanger类实现的,不需要我们重新造轮子。这个工具类在JDK1.5中已经引入,并不是一个“新特性”。Exchanger简介Exchanger是线程间的数据交换,只能用于两个线程之间的数据交换。Exchanger提供了两个公共方法:1.只有泛型V(交换数据对象)的方法,线程被阻塞直到任何其他线程与它交换数据,或者被线程中断;线程中断也是一门学问,栈龙在公众号Java技术栈有分享,大家可以在公众号搜索阅读;2.另一种带时间的方法,如果过了设定的时间没有线程与之交换数据,会抛出TimeoutException;Exchanger实战简单的数据交换下面是两个线程之间正常数据交换的简单例子:privatestaticvoidtest1(){Exchangerexchanger=newExchanger();newThread(()->{try{Objectdata="-公众号Java技术栈AAA";System.out.println(Thread.currentThread().getName()+data);//开始交换数据data=exchanger.exchange(data);System.out.println(Thread.currentThread().getName()+data);}catch(InterruptedExceptione){e.printStackTrace();}}).start();newThread(()->{try{Objectdata="-公众号Java技术栈BBB";System.out.println(Thread.currentThread().getName()+data);//开始交换数据data=exchanger.exchange(data);System.out.println(Thread.currentThread().get名称()+数据);}catch(InterruptedExceptione){e.printStackTrace();}}).start();}这段代码的逻辑:1.创建并启动两个线程;2.数据交换前首先打印出自己线程的数据;3.进行数据交换;4、数据交换后打印数据;输出结果:从结果可以看出,线程0和1分别打印出A和B,数据交换后,打印出B,A,数据交换正常!超时数据交换上面演示了两个线程的正常交换,这里再举一个超时的例子:privatestaticvoidtest2(){Exchangerexchanger=newExchanger();newThread(()->{try{Objectdata="-♂JavaTechnologyStackAAA";System.out.println(Thread.currentThread().getName()+data);//开始交换数据data=exchanger.exchange(data,3000L,TimeUnit.MILLISECONDS);系统.out.println(Thread.currentThread().getName()+data);}catch(Exceptione){e.printStackTrace();}}).start();}现在只启动了一个线程,超时时间为3秒的输出结果:首先该线程输出自己的数据,然后3秒后,没有其他线程与其交换数据,因此抛出超时异常,最后线程结束运行。本文所有案例源码已上传:https://github.com/javastacks...被中断的数据交换线程开始交换数据后,会一直阻塞,直到有其他线程与其交换数据,或者被中断interruptedortimedout,上面演示了Timeout,下面的例子演示了一个中断。privatestaticvoidtest3(){Exchangerexchanger=newExchanger();newThread(()->{try{Objectdata="-公众号Java技术栈AAA";System.out.println(Thread.currentThread().getName()+data);//开始交换数据data=exchanger.exchange(data);System.out.println(Thread.currentThread().getName()+data);}catch(Exceptione){e.printStackTrace();}}).start();}结果输出:默认情况下,如果不设置超时,它会一直阻塞运行...现在我将添加一段中断逻辑:privatestaticvoidtest3()throwsInterruptedException{Exchangerexchanger=newExchanger();Threadthread=newThread(()->{try{Objectdata="-公众号Java技术栈AAA";System.out.println(Thread.currentThread().getName()+data);//开始交换数据data=exchanger.exchange(data);System.out.println(Thread.currentThread().getName()+data);}catch(Exceptione){e.printStackTrace();}});thread.start();//线程中断Thread.sleep(3000L);thread.interrupt();}主线程休眠3秒后,中断线程输出结果:3秒后输出结果,线程被中断,抛出中断异常,线程停止阻塞,最后线程结束运行。关于成对数据交换需要了解的另一件事是,Exchanger只能用于两个线程之间的数据交换。一个线程开始数据交换后,它会阻塞,直到任何其他线程也开始数据交换并到达交换点。最后,这里有一个例子,启动10个线程,看看它们是如何两个两个交换的:privatestaticvoidtest4(){Exchangerexchanger=newExchanger();for(inti=1;i<=10;i++){整数数据=i;newThread(()->{try{Objectexchange=exchanger.exchange(data);System.out.println(Thread.currentThread().getName()+"-"+exchange);}catch(InterruptedExceptione){e.printStackTrace();}},"Java技术栈"+i).start();}}输出结果:可以看到有10个线程互相交换了数据。小结本文介绍线程间数据交换Exchanger类的使用。只能用于多线程中的两个线程成对交换数据。如果没有对应的线程交换,就会一直阻塞。可以设置超时和中断。.你都明白了吗?如果在面试中被问到,你需要掌握这个类的用法。当然还有其他的解决办法,但如果不是必须的,也没有必要另起炉灶。重新发明轮子时需要考虑更多方面。本文所有案例源码已上传:https://github.com/javastacks...欢迎Star学习,这??里将提供以下Java实例!好了,今天的分享就到这里。稍后栈长会分享更多有趣的Java技术和最新的技术资料。关注公众号Java技术栈第一时间推送。我也会分享主流的Java面试题和参考答案。全部搞定后在公众号后台回复关键词“面试”刷题。最后,如果觉得我的文章对你有用,动动你的小手,送给正在看的人,转发吧,原创不易,楼主需要你的鼓励。版权声明:本文为公众号《Java技术栈》原创。转载、引用本文内容请注明出处。抄袭、洗稿均属侵权投诉,后果自负,并保留追究法律责任的权利。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!
