关于线程和多线程,JAVA高并发程序设计

xiaoxiao2021-02-27  345


主要整理一些关于线程的知识,尽量做到言简意赅,面试的时候用。

线程

前段时间找工作,很多次问到关于线程的问题,回答的时候就开启背书模式:线程是轻量级的进程,是程序执行的最小单位….现在想想,面试官要听的肯定不是这些,如果只知道这些,那还怎么守护达康书记的GDP。


面试官:来说下线程吧。 程序猿:线程用的是Thread这个类和Runnable这个接口… 面试官:那你来说下Thread和Runnable的区别。 程序员:一个继承Thread方法,重写run()方法。另一个实现Runnable接的run()方法,两者都是通过start()方法实现多线程。

扩展:start()表示创建一个新的线程,而run()只是在当前线程里调用run()方法,Runnable和Thread比较:

JAVA是单继承,Thread有局限性;Runnable数据共享;

面试官:说下线程的几个方法。 程序员:主要用的是这么几个:

stop():停止线程,不过线程已经废弃了,因为这个方法太暴力了,说停就停。比如,A写一个数据data,B等待去读写到一半的时候,调用了stop,数据损坏,B此时去读的话,就是错误的数据了,解决方法就是,自定义停止线程的条件。wait()和notify():当一个对象调用了waut后,当前线程会一直等待,直到其他线程调用了notify。notify和notifyAll的区别:nofity在等待结束后,会随机抽取一个线程,nofityAll是所有线程。wait和sleep的区别:wait可以重新唤醒,会释放目标对象的锁。大概是下图那个意思,重点是流程,现实中开明的父母还是很多的哈suspend()和resume():不推荐用,不会释放锁。join()和yield():join是等待线程完成后再去执行.。比如: class OneThread extends Thread{ @Override public void run() { for(int i =0;i<1000000;i++); } } 直接调用OneThread.start(),输出i结果会很小,调用OneThread.join,会等待线程执行完成,输出i=1000000。

面试官:说一下volatile吧。 程序猿:volatile修饰表示不能随意改变目标指令。 这跟JAVA的内存模型有关系,JVM的三个特征:

原子性:不能中断,比如int a,两个线程无论用任何方式赋值,最后a的结果只能是两个中的一个。PS:long类型比较特殊,因为他有64位,在32为系统上有出入。可见性:窜行程序,可见性问题不存在,修改值后,后续的操作都是修改后的值。并行程序会出现问题:A修改了一个全局变量,其他线程不一定知道。有序性:指令重排,后面的代码肯呢个会先执行,无法判断会不会出现这个问题,同样在窜行中不会出现。 在实际的运用中,我们常用的单例模式,比较好的写法其实是这样: public class Simple{ private static volatile Simple simple; public static Simple getInstance(){ if (null == simple) { synchronized (Simple.class) { if (null == simple) { simple = new Simple(); } } } return simple; } }

这样写效率低了些,但保证了安全性。


面试官:说下synchronized的作用 程序员:实现线程间的同步,对需要同步的代码加锁,比如A在写入时,B不能读也不能写,保证线程间的安全性。主要的几种用法:

指定对象加锁;作用于实例方法;作用于静态方法;

最后会问一些其他跟线程有关的问题,比如HashMap,ArrayList是线程安全吗?为什么?这些网上都有很多,可以去找下这方面的资料

有哪里说错的或是不好的,欢迎留言。最后感叹下,现在的公司对技术要求越来越高了

转载请注明原文地址: https://www.6miu.com/read-1625.html

最新回复(0)